如何在 AsyncTask 中更新 ArrayList 的内容?

Posted

技术标签:

【中文标题】如何在 AsyncTask 中更新 ArrayList 的内容?【英文标题】:How to update contents of ArrayList in AsyncTask? 【发布时间】:2014-05-14 19:14:43 【问题描述】:

我要做的是从我的 json 文件中获取名称列表并将其存储到 ArrayList 中。我使用 getPointsList() 方法实现了一个名为 ServiceHandler 的类。所有的值和对象传递似乎都是正确的,所以我想知道这是否是我运行 AsyncTask 的问题。错误日志似乎返回 NullPointerException 语句 这是服务处理程序

public class ServiceHandler 
    private static String pt_url="full url name here";
    private static final String TAG_NAME = "name";
    private static final String TAG_LON = "gps_lon";
    private static final String TAG_LAT = "gps_lat";

ArrayList<String> PList;

static String response = null;
public final static int GET = 1;
public final static int POST = 2;
static InputStream is= null;
static JSONObject jObj=null;
ProgressDialog pDialog;
Activity A;
JSONArray json;

public ServiceHandler(Activity A) 
    this.A=A;


/**
 * Making service call
 * @url - url to make request
 * @method - http request method
 * */
public String makeServiceCall(String url, int method) 
    return this.makeServiceCall(url, method, null);


/**
 * Making service call
 * @url - url to make request
 * @method - http request method
 * @params - http request params
 * */
public String makeServiceCall(String url, int method,
        List<NameValuePair> params) 
    try 
        // http client
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpEntity httpEntity = null;
        HttpResponse httpResponse = null;

        // Checking http request method type
        if (method == POST) 
            HttpPost httpPost = new HttpPost(url);
            // adding post params
            if (params != null) 
                httpPost.setEntity(new UrlEncodedFormEntity(params));
            

            httpResponse = httpClient.execute(httpPost);

         else if (method == GET) 
            // appending params to url
            if (params != null) 
                String paramString = URLEncodedUtils
                        .format(params, "utf-8");
                url += "?" + paramString;
            
            HttpGet httpGet = new HttpGet(url);

            httpResponse = httpClient.execute(httpGet);

        
        httpEntity = httpResponse.getEntity();
        response = EntityUtils.toString(httpEntity);

     catch (UnsupportedEncodingException e) 
        e.printStackTrace();
     catch (ClientProtocolException e) 
        e.printStackTrace();
     catch (IOException e) 
        e.printStackTrace();
    

    return response;



public ArrayList<String> getPointsList() throws JSONException
    GetPoints AT = new GetPoints();
    pDialog = new ProgressDialog(A);
    pDialog.setMessage("Retreiving points...");
    pDialog.setCancelable(false);
    pDialog.show();
    AT.execute(pt_url);

    PList = new ArrayList<String>();
    int i;
    Log.d("",""+AT.getStatus());

如果我删除 !它永远不会通过 if 语句,问题在于 AsyncTask 连续运行

if(!(AT.getStatus().equals(AsyncTask.Status.FINISHED)))
            if (pDialog.isShowing()) pDialog.dismiss();
            Log.d("Status: ",AT.getStatus().toString());
            for (i = 0; i < json.length(); i++) 
                JSONObject c = json.getJSONObject(i);
                Log.i("Name of Object: "+i,c.getString(TAG_NAME));
                PList.add(c.getString(TAG_NAME));
                //LatList.add(c.getDouble(TAG_LAT));
                //LonList.add(c.getDouble(TAG_LON));
            
        
        return PList;
    

    public class GetPoints extends AsyncTask<String, Void, JSONArray>

        @Override
        protected void onPreExecute() 
            super.onPreExecute();
            /*pDialog = new ProgressDialog(A);
            pDialog.setMessage("Retreiving points...");
            pDialog.setCancelable(false);
            pDialog.show(); */
        

        @Override
        protected JSONArray doInBackground(String... arg)
            //ServiceHandler sh = new ServiceHandler();

            //Log.i("arg[0]",arg[0]);
            // Making a request to url and getting response
            String ptStr = makeServiceCall(arg[0], GET);

            Log.d("Response: ", "> " + ptStr);

            if (ptStr != null) 
                try 
                    json = new JSONArray(ptStr); 
                    //Log.d("New json: ", json.toString());
                 catch (JSONException e) 
                        e.printStackTrace();
                
             else 
                Log.e("ServiceHandler", "Couldn't get any data from the url"); 
                //PList.add("some text");
            
            return json;
        

        @Override
        protected void onPostExecute(JSONArray result)
            super.onPostExecute(result);
            //Log.d("New json: ", json.toString());
            // Dismiss the progress dialog
            /*if (pDialog.isShowing())
                pDialog.dismiss();*/
            //for(String entry: PList)
            //  Log.i("GETPOINTS", entry);  
            //  

            /* Adapters are updated here, so change this to fit whatever we use in UI
            stAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, FList);
            festAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            inputFest.setAdapter(festAdapter);
                            */
        
    


这是错误日志

    04-03 02:22:37.480: E/AndroidRuntime(18824): FATAL EXCEPTION: main
04-03 02:22:37.480: E/AndroidRuntime(18824): java.lang.NullPointerException
04-03 02:22:37.480: E/AndroidRuntime(18824):    at com.example.demo.ServiceHandler.getPointsList(ServiceHandler.java:123)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at com.example.demo.MainMenuActivity$2.onClick(MainMenuActivity.java:70)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.view.View.performClick(View.java:4198)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.view.View$PerformClick.run(View.java:17158)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.os.Handler.handleCallback(Handler.java:615)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.os.Handler.dispatchMessage(Handler.java:92)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.os.Looper.loop(Looper.java:137)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at android.app.ActivityThread.main(ActivityThread.java:4918)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at java.lang.reflect.Method.invokeNative(Native Method)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at java.lang.reflect.Method.invoke(Method.java:511)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
04-03 02:22:37.480: E/AndroidRuntime(18824):    at dalvik.system.NativeStart.main(Native Method)
04-03 02:22:37.680: D/Response:(18824): > ["id":"5","name":"The Hendrix Center","gps_lat":"34.67605277777778","gps_lon":"-82.831825","campus_id":"1","id":"7","name":"Red Fern","gps_lat":"34.67575","gps_lon":"-82.83358055555556","campus_id":"1","id":"9","name":"McAdams Hall","gps_lat":"34.67559166666666","gps_lon":"-82.83461388888888","campus_id":"1","id":"10","name":"Edwards Hall","gps_lat":"34.67681666666667","gps_lon":"-82.83379166666666","campus_id":"1","id":"11","name":"Vickory Hall","gps_lat":"34.677375","gps_lon":"-82.83379722222222","campus_id":"1","id":"12","name":"Daniel Hall","gps_lat":"34.67714722222222","gps_lon":"-82.8351611111111","campus_id":"1","id":"13","name":"Kinard Hall","gps_lat":"34.677524999999996","gps_lon":"-82.83515","campus_id":"1","id":"14","name":"Martin Hall","gps_lat":"34.67805833333333","gps_lon":"-82.83553055555555","campus_id":"1"]

【问题讨论】:

第 123 行是什么? 你调试应用程序并找到你在哪里得到空指针 问题在于第 123 行的 for 循环,因为 AsyncTask 似乎永远不会完成,这意味着 json 保持为空。所以问题一定是在 AsyncTask 没有结束。 不清楚您的 AT.getStatus 检查代码在哪里执行?您不只是使用 postExecute 方法运行该代码的任何原因(然后您不需要 AT 状态检查,因为该方法在 toInBackground 完成后调用 【参考方案1】:

在 getPointsList() 中你这样做:

for (i = 0; i < json.length(); i++) 
  JSONObject c = json.getJSONObject(i);

变量 json 为空,因为 ASyncTask 尚未完成。

【讨论】:

是的,这就是我尝试使用 (AT.getStatus().equals(AsyncTask.Status.FINISHED)) 的原因 AsyncTask 以某种方式持续运行,但是当我打印到登录 onPostExecute() 时它没有问题。所以我的假设是 AsyncTask 正在执行它的最终方法。

以上是关于如何在 AsyncTask 中更新 ArrayList 的内容?的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 中,如何从 AsyncTask 更改 TextView? [复制]

如何使用 AsyncTask 更新 RecyclerView 项目

重新创建活动时如何从 AsyncTask 更新 TextView

如何使用 AsyncTask 更新全局变量

如何使用 AsyncTask 的 onPostExecute 方法更新 Android 中的变量

如何在Android开发中用AsyncTask异步更新UI界面