Przypisanie wartości do zmiennej w onPostExecute do głównej aktywności

0

Witam!
Mam taki problem bardzo irytujący. Szukałem odpowiedzi ale nie znalazłem, pasującej do mojego przypadku.

Mam taką aktywność.
Mam zmienna "globalną" w tej aktywności String json_string chce do niej przypisać wartość result z Metody onPostExecute(), ale jej nie przypisuje.
Co dziwne jak dam w onPostExecute() tak:
json_string = result;
json_textview.setText(json_string);
To wtedy wszystko śmiga, ale ja nie chce tej zmiennej jako textview tylko potrzebują ją mieć w stringu, aby potem jej użyć w DisplayListView(), no ale nie chce przypisać mi tej cholernej zmiennej. Przeszukałem troche internetu, sam stracilem duzo czasu i za nic nie mam pomysłu aby to rozwiązac.

Prosze o pomoc.

public class AfterLoginActivity extends AppCompatActivity {

    private TextView textView;
    private TextView json_textview;
    private String json_string;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        textView = (TextView)findViewById(R.id.textView);
        json_textview = (TextView)findViewById(R.id.json_textview);

        SharedPreferences sharedPreferences = getSharedPreferences(Config.SHARED_PREF_NAME, Context.MODE_PRIVATE);
        String login = sharedPreferences.getString(Config.LOGIN_SHARED_PREF, "Coś się popsuło");
        textView.setText("Current user: " + login);

        new BackgroundLoadData().execute();

        DisplayListView();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
      // kod usuniety aby nie zaciemniac
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

    // kod usuniety aby nie zaciemniac
    }

    private void logout(){
// kod usuniety aby nie zaciemniac
            }
        });
    }

    class BackgroundLoadData extends AsyncTask<Void,Void,String>{

        private String JSON_STRING;
        Context context;
        public BackgroundLoadData() {
            super();
        }
        BackgroundLoadData(Context ctx){
            context = ctx;
        }

        @Override
        protected String doInBackground(Void... params) {

            try {
                URL url = new URL(Config.GET_JSON_DATA_URL);
                HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder stringBuilder = new StringBuilder();
                while((JSON_STRING = bufferedReader.readLine())!= null){
                    stringBuilder.append(JSON_STRING + "\n");
                }
                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();
                return stringBuilder.toString().trim();

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
           // json_textview.setText(result);
            json_string = result;
          //  json_textview.setText(json_string);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
        }
    }

    public void DisplayListView(){
        String name, date, time;
        JSONObject jsonObject;
        JSONArray jsonArray;
        ItemAdapter itemAdapter = new ItemAdapter(this,R.layout.textview_element);
        ListView listView = (ListView)findViewById(R.id.listView);
        listView.setAdapter(itemAdapter);

        try {
            jsonObject = new JSONObject(json_string);
            jsonArray = jsonObject.getJSONArray("server_response");

            for(int i = 0 ; i < jsonArray.length();i++){
                JSONObject JO = jsonArray.getJSONObject(i);
                name = JO.getString("name");
                date = JO.getString("date");
                time = JO.getString("time");
                Items items = new Items(name, date, time);
                itemAdapter.add(items);
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }
}
1

Po 1, ten kod to crap. Po 2, przypisuje tylko, że metoda DisplayListView() jest wywołana zanim json_string jest ustawione (zanim się wykona metoda onPostExecute) więc zapewne dostajesz JSONException.

Polecam wrócić do podstaw programowania, Javy, Androida..

0

Dokładnie otrzymuje to: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference

Hm, mogłbys jaśniej z tym, że przypisuje "metoda DisplayListView() jest wywołana zanim json_string jest ustawione" ?
Ja zdaje sobie sprawę że to jest wywoływane asynchronicznie, to czyli metoda DisplayListView() jest wywoływana w momencie jak background nie został jeszcze zakończony?
Czyli jak w takim razie ustawić to aby przypisał wartość i wywołał w odpowiedniej kolejności?

Co do kodu, tak, wyglada fatalnie ale zostanie on uprzątnięty jak wszystko posklejam do kupy, na razie jest tam wiele 'luźnych myśli' i sprawdzenie jedynie czy działa.

0

https://developer.android.com/training/basics/activity-lifecycle/starting.html
oraz pierwszy akapit z
https://developer.android.com/reference/android/os/AsyncTask.html

Jeśli wyskakuje ci błąd, to tak jak wyżej napisano

 private String json_string;

masz bez żadnej wartości w momencie wywołania metody DisplayListView();

Wywołujesz najpierw kod z onCreate() w klasie nadrzędnej, tam jak widać inicjujesz BackgroundLoadData(), z tym, że jest to AsyncTask() więc kod stamtąd nie zostaje wykonany przed przejściem do kolejnych kroków z onCreate() (chodzi mi o pobranie danych z web). Zanim json_string dostaje wartość w onPostExecute() zostaje wywołana metoda DisplayListView(); która wymaga jakiejś wartości dla tego stringa. Wartości nie ma, więc masz błąd. Kolejność wywoływania kodu.

Wartość zostaje nadana w onPostExecute() - ono zostanie tutaj wywołane już po onCreate(), z tym, że nic konkretnego to już nie daje.

Fragment

 json_textview.setText(json_string);

nadpisuje wartość w TextView ponieważ masz już wtedy string z wartością.

Mam skromną wiedzę o tym, ale tak na zdrowy rozum po przyjrzeniu się kodowi.

Ps. wstawiłeś w tym kodzie DisplayListView() które wymaga tego stringa z wartością do onCreate(). Bolson pisał o tym.

0

Gregoryl, teraz jak sobie wyobrazilem po Twoim poście co chciałem zrobić to aż mi głupio, zasugerowałem się tym że jak Textview dostaje stringa i wywala na ekran to znaczy że string dostaje wartość, a to działa tak że odpala backgroundloaddata, w backgroundzie i dalej sobie jedzie z linijkami kodu. I po prostu postexecute nie zostaje wywołany przed displaylistview.

Czyli powinno pomóc jak wywołam funkcje displaylistview z postexecute bezpośredni? Dobrze myślę? Czy na takie myki istnieją jakieś ładne sposoby?

Przepraszam za styl pisania ale pisze z telefonu na ten moment.

1

Wywołanie displayListView() z onPostExecute() załatwi sprawę. W tym kodzie masz jeszcze jeden problem a mianowicie potencjalny wyciek pamięci ;) Ale to już sobie znajdź sam, hint: "android activity async task memory leak".

0

Dziękuje Bardzo za rady.

Z tym wyciekiem pamięci, to dziękuje za zwrócenie uwagi. Faktycznie wątek asynchroniczny nie jest kończony obecnie razem z inną aktywnością.

1 użytkowników online, w tym zalogowanych: 0, gości: 1