java - AsyncTask 中的 ArrayAdapter 出错

标签 java android android-asynctask android-arrayadapter

我有以下代码,但在“userSpinner.setAdapter(adapter);”这一行出现错误

 private class Task extends AsyncTask<Void, Void, Void> 
 { 
     protected void onPreExecute() {            
     showDialog(DIALOG_TASKING); 
     } 
     protected Void doInBackground(Void... JSONArray) { 

        try
        {
        HttpGet request = new HttpGet(SERVICE_URI + "/GetBusNames");
        request.setHeader("Accept", "application/json");
        request.setHeader("Content-type", "application/json");

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpResponse response = httpClient.execute(request);
        HttpEntity responseEntity = response.getEntity();

        char[] buffer = new char[(int)responseEntity.getContentLength()];
        InputStream stream = responseEntity.getContent();       
        InputStreamReader reader = new InputStreamReader(stream);
        reader.read(buffer);
        stream.close();

        JSONObject jsonResponse = new JSONObject(new String(buffer));
        JSONArray myUsers = jsonResponse.getJSONArray("GetBusNamesResult");

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(RealestateActivity.this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        adapter.add("Select a Buseness...");                
        for (int i = 0; i < myUsers.length(); ++i)
        {
            adapter.add(myUsers.getString(i));
            adapter.add(myUsers.getJSONObject(i).getString("BusName"));
        }

            userSpinner.setAdapter(adapter); // I get an error here if I wrap these two lines in /*...*/ the whole thing loads as expected but the spinner is empty
            userSpinner.setOnItemSelectedListener(new MyOnItemSelectedListener());

        }
        catch (Exception e) 
        {       
            e.printStackTrace();
            displayExceptionMessage(e.getMessage());
        }
        return null;
    }

    protected void onPostExecute(Void unused) {
        dismissDialog(DIALOG_TASKING);              
    } 

下面是产生的Stack Trace,

11-07 19:54:35.300: ERROR/AndroidRuntime(8741): FATAL EXCEPTION: AsyncTask #1
11-07 19:54:35.300: ERROR/AndroidRuntime(8741): java.lang.RuntimeException: An error occured while executing doInBackground()
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.lang.Thread.run(Thread.java:1096)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at android.os.Handler.<init>(Handler.java:121)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at android.widget.Toast.<init>(Toast.java:68)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at android.widget.Toast.makeText(Toast.java:231)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at com.fnesse.realestate.RealestateActivity.displayExceptionMessage(RealestateActivity.java:271)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at com.fnesse.realestate.RealestateActivity$Task.doInBackground(RealestateActivity.java:131)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at com.fnesse.realestate.RealestateActivity$Task.doInBackground(RealestateActivity.java:1)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-07 19:54:35.300: ERROR/AndroidRuntime(8741):     ... 4 more
11-07 19:56:22.714: ERROR/PowerManagerService(2464): CurLock p:3 mPS:1
11-07 20:06:26.577: ERROR/libnetutils(2464): dhcp start cmd 11 : [dhcpcd:-ABK] 
11-07 20:06:27.054: ERROR/HierarchicalStateMachine(2464): TetherMaster - unhandledMessage: msg.what=3

代码在其自己的方法中运行,但在 AsyncTask 中不起作用。

任何想法。

干杯,

迈克。

最佳答案

您不能在 doInBackground() 方法中执行显示/更新 UI,而是可以通过实现 runOnUIThread() 方法或在 onPostExecute() 方法中编写显示/更新语句来执行。

在您的情况下,在 onPostExecute() 中编写以下语句并在类级别声明 JSONArray myUsers:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(RealestateActivity.this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        adapter.add("Select a Buseness...");                
        for (int i = 0; i < myUsers.length(); ++i)
        {
            adapter.add(myUsers.getString(i));
            adapter.add(myUsers.getJSONObject(i).getString("BusName"));
        }

            userSpinner.setAdapter(adapter); // I get an error here if I wrap these two lines in /*...*/ the whole thing loads as expected but the spinner is empty
            userSpinner.setOnItemSelectedListener(new MyOnItemSelectedListener());

        }
        catch (Exception e) 
        {       
            e.printStackTrace();
            displayExceptionMessage(e.getMessage());
        }

最终解决方案:

private class Task extends AsyncTask<Void, Void, Void> 
 { 
    JSONArray myUsers = null;
    JSONObject jsonResponse = null;  // this is also needed at class level

     protected void onPreExecute() {            
         showDialog(DIALOG_TASKING); 
     } 
     protected Void doInBackground(Void... JSONArray) { 

        try
        {
        HttpGet request = new HttpGet(SERVICE_URI + "/GetBusNames");
        request.setHeader("Accept", "application/json");
        request.setHeader("Content-type", "application/json");

        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpResponse response = httpClient.execute(request);
        HttpEntity responseEntity = response.getEntity();

        char[] buffer = new char[(int)responseEntity.getContentLength()];
        InputStream stream = responseEntity.getContent();       
        InputStreamReader reader = new InputStreamReader(stream);
        reader.read(buffer);
        stream.close();

        jsonResponse = new JSONObject(new String(buffer));
        }
        catch (Exception e) 
        {       
            e.printStackTrace();
            displayExceptionMessage(e.getMessage());
        }
        return null;
    }

    protected void onPostExecute(Void unused) {
        dismissDialog(DIALOG_TASKING);    

 myUsers = jsonResponse.getJSONArray("GetBusNamesResult");

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(RealestateActivity.this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        adapter.add("Select a Buseness...");                
        for (int i = 0; i < myUsers.length(); ++i)
        {
            adapter.add(myUsers.getString(i));
            adapter.add(myUsers.getJSONObject(i).getString("BusName"));
        }

            userSpinner.setAdapter(adapter); // I get an error here if I wrap these two lines in /*...*/ the whole thing loads as expected but the spinner is empty
            userSpinner.setOnItemSelectedListener(new MyOnItemSelectedListener());          
    } 

关于java - AsyncTask 中的 ArrayAdapter 出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8034587/

相关文章:

android - 执行 AsyncTask 时替换 fragment - getActivity() 上的 NullPointerException

java - 如何将ArrayList从AsyncTask返回到另一个类?

java - 验证对静态方法的调用

android - canvas.setBitmap(bitmap) 在模拟器中有效,但在手机上无效

java - 如何按日期设置文本并增量循环android?

java - 如何使用异步任务

java - 空接口(interface) - 对象关系建模

java - 实例化/从枚举返回时类型安全的接口(interface) (Java)

java - 如何允许访问类(class)?

java - 长按无法卸载应用程序