在AsyncHttpResponseHandler中编辑GUI

时间:2014-01-02 21:11:02

标签: android multithreading android-asynctask

我正在尝试根据我从AsyncHttpResponseHandler获得的响应来编辑我的GUI,但是我遇到了线程权限的问题。

这是我的onCreate方法

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

    final ProgressDialog ringProgressDialog = ProgressDialog.show(
            MainActivity.this, "Please wait ...", "Setting up network...",
            true);
    ringProgressDialog.setCancelable(true);
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                setUpNetwork();
                Thread.sleep(5000);
                GetList getList = new GetList(
                        getApplicationContext());
                getList.execute();

            } catch (Exception e) {

            }
            ringProgressDialog.dismiss();
        }
    }).start();
}

setUpNetwork向我提供了AsyncTask应发送到的IP地址,因此AsynTask在完成之前不会启动至关重要。

我的GetList看起来像这样

private class GetList extends AsyncTask<Void, Void, Void> {

    Context context;

    public GetList(Context applicationContext) {
        context = applicationContext;
    }

    @Override
    protected String doInBackground(Void... params) {
        // this stores my list in a static way so I can access it across my Activities
        User u = StaticVars.getUserList().get(0);
        tblLayout = (TableLayout) findViewById(R.id.song_list_table);
        AsyncHttpClient client = new AsyncHttpClient();
        client.post(context, url, entity, contentType, new AsyncHttpResponseHandler() {

            @Override
            public void onSuccess(int statusCode, Header[] headers,
                    byte[] responseBody) { 
                Log.d(TAG, "Successfully got a response: "
                        + new String(responseBody));
                String response = new String(responseBody);

                TextView tv = new TextView(context);
                tv.setText(response);
                TableRow tr = new TableRow(context);
                tr.addView(tv);
                tblLayout.addView(tr);

            }
        }
    }
}

现在当AsyncTask启动时,我收到的错误是无法从没有创建它的线程编辑视图。

01-02 22:01:00.454: E/AndroidRuntime(7905): FATAL EXCEPTION: AsyncTask #1
01-02 22:01:00.454: E/AndroidRuntime(7905): java.lang.RuntimeException: An error occured while executing doInBackground()
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.FutureTask.run(FutureTask.java:239)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.lang.Thread.run(Thread.java:841)
01-02 22:01:00.454: E/AndroidRuntime(7905): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that    created a view hierarchy can touch its views.
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6804)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1077)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.View.requestLayout(View.java:16775)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.View.requestLayout(View.java:16775)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.View.requestLayout(View.java:16775)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.View.requestLayout(View.java:16775)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.View.requestLayout(View.java:16775)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.widget.TableLayout.requestLayout(TableLayout.java:230)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.ViewGroup.addView(ViewGroup.java:3608)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.widget.TableLayout.addView(TableLayout.java:429)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.ViewGroup.addView(ViewGroup.java:3555)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.widget.TableLayout.addView(TableLayout.java:411)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.view.ViewGroup.addView(ViewGroup.java:3531)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.widget.TableLayout.addView(TableLayout.java:402)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at com.app.main.MainActivity$GetList.doInBackground(MainActivity.java:295)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at com.app.main.MainActivity$GetList.doInBackground(MainActivity.java:1)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
01-02 22:01:00.454: E/AndroidRuntime(7905):     at java.util.concurrent.FutureTask.run(FutureTask.java:234)
01-02 22:01:00.454: E/AndroidRuntime(7905):     ... 4 more

这是一个主要的设计缺陷还是有什么办法可以解决这个问题?

1 个答案:

答案 0 :(得分:1)

您可以在runOnUiThread中调用AsyncHttpResponseHandler或存储视图,并将其添加到AsyncTasks覆盖方法onPostExecute(Result result)中。我不确定AsyncHttpResponseHandler究竟是如何工作的,所以你可能不得不使用runOnUiThread而不是正确的onPostExecute方法。