简体   繁体   中英

How can I use a variable outside the onPostExecute method?

I have a MySQL database on a webserver and I read the data from this database in my application, but after I read the variables I can't use the "volt" variable outside the onPostExecute. I try t use adapter, but i can't use the data in the adapter like a intiger variable, just i can add to listview. So far i Don't find a solution for my problam. I hope you can help me.

 package com.example.wifis;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;

public class MainActivity extends AppCompatActivity {
    ListView listView;
    ArrayAdapter<String> adapter;
   // int tomb []={};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView=(ListView)findViewById(R.id.list_item);
        adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        listView.setAdapter(adapter);
        new Conection().execute();
    }





    class  Conection extends AsyncTask<String, String, String>{


        @Override
        public String doInBackground(String... strings) {
            String result="";
            String host="http://localhost/store/cars.php";
            try {
                HttpClient client = new DefaultHttpClient();
                HttpGet request = new HttpGet();
                request.setURI(new URI(host));
                HttpResponse response =  client.execute(request);
                BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

                StringBuffer stringBuffer= new StringBuffer("");

                String line = "";
                while ((line = reader.readLine()) !=null ){
                    stringBuffer.append(line);
                    break;
                }
                reader.close();
                result = stringBuffer.toString();
            }
            catch (Exception e){
                return  new String("There exeption: "+ e.getMessage());
            }


            return result;
        }
        @Override
        public void onPostExecute(String result){
 //           Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
            JSONObject jsonResult = null;
            try {
                jsonResult = new JSONObject(result);
                int success = jsonResult.getInt("success");
                if(success==1){


                        JSONArray cars = jsonResult.getJSONArray("cars");
                        JSONObject car = cars.getJSONObject(0);
                        int id = car.getInt("id");
                        int volt = car.getInt("szam");
                        String line = id + "-" + volt;
                        adapter.add(line);
                      //  tomb[0]=szam;



                }else{
                    Toast.makeText(getApplicationContext(), "NOT OK ", Toast.LENGTH_SHORT).show();
                }

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


        }



    }
}

As I have tried to explain in my post here

the values you're trying to access aren't synchronous, meaning that your code does not execute top down. The AsyncTask returns a value at some point . we don't know when that will be, but when it returns the value, you'll have access to it within onPostExecute . this means that you can make use of the values as they are received there and only there, as that is the only place where you'll actually receive those values.

to get this value returned to your main activity, you can do something like this:

create an interface

public interface MyCallback {
    void myResult(YourResultType output); //here, i believe this will be string for your specific case
}

This interface allows us to move the value we receive to another class when it's received

Next,

Go to your AsyncTask class, and declare interface MyCallback as a variable:

public class MyAsyncTask extends AsyncTask<String, String, String> {
  public MyCallback callback = null;

    @Override
    protected void onPostExecute(String result) {
      callback.myResult(result);
    }
 }

@Override
    protected void onPostExecute(String result) {
      callback.myResult(result);
    }

now for your main activity:

public class MainActivity implements MyCallback {
  MyAsyncTask asyncTask = new MyAsyncTask();

  @Override
  public void onCreate(Bundle savedInstanceState) {

     //set your listener to this class
     asyncTask.callback = this;

     //execute the async task 
     asyncTask.execute();
  }

  //this overrides the implemented method from asyncTask
  @Override
  void myResult(YourResultType output){
     //Here you will receive the result returned from the async task
   }
 }

please also note that async tasks are deprecated

also note, my java is quite rusty, I am fortunate enough to only use kotlin these days, feel free to correct me on any mistakes:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM