从void AsyncTask返回ArrayList

时间:2016-09-22 11:28:08

标签: android android-asynctask

Googled很多,但没有机会。 现在,我有一个Inner AsyncTask类,我想在上层使用返回值。 它成功运作,因为我放了一个Log.e()它显示了我的价值,这是我的代码:

   public class Consume extends AsyncTask<Void, Void, Void> {
        private List<LatLng> latLngs = new ArrayList<>();
        private List<ContactModel> contacts = new ArrayList<>();
        InputStream inputStream = null;
        String result = "";

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

            String URL = "http://x.x.x.x/MYWCF/Service1.svc/Json/getContact";
            ArrayList<NameValuePair> param = new ArrayList<NameValuePair>();
            try {
                HttpClient httpClient = new DefaultHttpClient();
                HttpPost post = new HttpPost(URL);
                post.setEntity(new UrlEncodedFormEntity(param));
                HttpResponse httpResponse = httpClient.execute(post);
                HttpEntity httpEntity = httpResponse.getEntity();
                inputStream = httpEntity.getContent();

            } catch (UnsupportedEncodingException e1) {
                Log.e("UnsupportedEncoding", e1.toString());
                e1.printStackTrace();
            } catch (ClientProtocolException e2) {
                Log.e("ClientProtocolException", e2.toString());
                e2.printStackTrace();
            } catch (IllegalStateException e3) {
                Log.e("IllegalStateException", e3.toString());
                e3.printStackTrace();
            } catch (IOException e4) {
                Log.e("IOException", e4.toString());
                e4.printStackTrace();
            }
            try {
                BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
                StringBuilder sBuilder = new StringBuilder();

                String line = null;
                while ((line = bReader.readLine()) != null) {
                    sBuilder.append(line + "\n");
                }
                inputStream.close();
                result = sBuilder.toString();
            } catch (Exception e) {
                Log.e("StringBuilding", "Error converting result " + e.toString());
            }
            return null;
        }
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            List<ContactModel> contactModels;
            List<LatLng> myLatLngs = new ArrayList<>();
            try {

                JSONObject object = new JSONObject(result);
                JSONArray jArray = object.getJSONArray("getContactResult");

                Type listType = new TypeToken<List<ContactModel>>() {
                }.getType();
                contactModels = new Gson().fromJson(String.valueOf(jArray), listType);
                setContacts(contactModels);

                setContacts(contactModels);
                for(ContactModel contactModel : contactModels) {
                    Double latitude = Double.valueOf(contactModel.getLatitude());
                    Double longitude = Double.valueOf(contactModel.getLongitude());
                    LatLng latLong = new LatLng(latitude, longitude);
                    myLatLngs.add(latLong);
                }
                setLatLngs(myLatLngs);
                Log.e("SizeOfArray", myLatLngs.size()+"");
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

    public void setContacts(List<ContactModel> contacts) {
        this.contacts = contacts;
    }

    public List<ContactModel> getContacts() {
        return contacts;
    }

    public void setLatLngs(List<LatLng> latLngs) {
        this.latLngs = latLngs;
    }
    public List<LatLng> getLatLngs() {
        return latLngs;
    }

在我的Activity Class

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


    Consume consume = new Consume();
    consume.execute();

当我运行应用程序时,行的原因是:

                Log.e("SizeOfArray", myLatLngs.size()+"");

它返回logcat中数组大小的正确int数,但我想在我的应用程序中使用它, 我甚至用doInBackground方法做所有事情,甚至做一个static变量, 没有机会。 任何人都可以通过我的代码提供真实样本吗? THX

3 个答案:

答案 0 :(得分:0)

首先,我要说你应该使用静态内部类而不是非静态内部类来避免内存泄漏,因为非静态内部类保存对外部类的引用。另一件事是您可以传递WeakReference外部父类,以便您可以从AsyncTask的onPostExecute()返回值,如

public static class Consume extends AsyncTask<Void, Void, Void> {

    WeakReference<MainActivity> mActivity;

    public Consume(MainActivity activity){
        mActivity = new WeakReference<SampleActivity>(activity);
     }
}

在AsyncTask的onPostExecute方法中,它将是

mActivity.response(latLngs);

在你的另一堂课中,它就像

private static void response(List<LatLng> latLngs){
   // handle response here in your outer class
}

更新Here是如何将Activity的WeakReference传递给Inner或Anonymous类并使用它。

答案 1 :(得分:0)

至于AsyncTask类是一个内部类。它可以直接访问外部类的对象。

在外层等级创建下面的对象。

List<LatLng> myLatLngs = new ArrayList<>();

从内部类中删除它,以便单个对象实例成为它们。

另一种方法是使用内部asyntask的回调,你需要让接口回调到外部类来开始进一步的过程。

interface CallBack {
    public void processingDone();
}

Consume consume = new Consume(new CallBack() {
   @Override
   public void processingDone(List<LatLng> mLatLngs) {
     // Do your stuff here
   }
});
consume.execute();

在Consume构造函数中存储回调以将数据传递回外部类。

class Consume {
  private Callback mCallback;
  public Consume(Callback callback) {
     mCallback = callback;
  }
}

从下面链接你可以做到

if (mCallback != null) {
  mCallback.processingDone(myLatLngs);
}
Log.e("SizeOfArray", myLatLngs.size()+"");

答案 2 :(得分:0)

总而言之,对于所有回复。 谢谢,我真的不明白问题是什么,原因是我问了这个简单的问题!不幸的是,没有人注意到这一点。 代码之后:

onPre

编译器也会执行下一个代码,导致consume.execute()启动另一个线程,但主线程继续。 因为我收到了我想要的延迟值,因此我虽然问题是如何获得价值, 但实际上问题是我无法处理线程异步。 所以我在AsyncTask类的onPostpublic string GenerateHash(string[] values) { var secureSecret = "a secret string"; //<-- this can/should be const var str = new StringBuilder(secureSecret); foreach (var value in values) { str.Append(value); } return GenerateMd5Hash(str.ToString()); } 方法中移动了所有它们,然后它工作了!