在AsyncTask中添加视图(文本视图)

时间:2013-07-26 07:25:11

标签: java android view android-asynctask

我使用下面的代码在Async任务中添加文本视图,但是:

07-26 11:40:39.302: E/AndroidRuntime(26715): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
07-26 11:40:39.312: E/AndroidRuntime(26715): java.lang.RuntimeException: An error occured while executing doInBackground()
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.os.AsyncTask$3.done(AsyncTask.java:200)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.lang.Thread.run(Thread.java:1096)
07-26 11:40:39.312: E/AndroidRuntime(26715): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewRoot.checkThread(ViewRoot.java:2683)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewRoot.invalidateChild(ViewRoot.java:570)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:596)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:2481)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.View.invalidate(View.java:5027)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewGroup.addView(ViewGroup.java:1840)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.view.ViewGroup.addView(ViewGroup.java:1821)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at com.learning.chiazi.MainActivity.addTextView(MainActivity.java:180)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at com.learning.chiazi.MainActivity$Proccess.doInBackground(MainActivity.java:243)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at com.learning.chiazi.MainActivity$Proccess.doInBackground(MainActivity.java:1)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-26 11:40:39.312: E/AndroidRuntime(26715):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
07-26 11:40:39.312: E/AndroidRuntime(26715):    ... 4 more
07-26 11:40:39.342: E/SemcCheckin(26715): Get crash dump level : java.io.FileNotFoundException: /data/semc-checkin/crashdump

我该如何解决这个问题?

代码:

   public void addTextView(int belowId, int id,String text){
        RelativeLayout rSub= (RelativeLayout) findViewById(R.id.rSub);
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT,
                RelativeLayout.LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.BELOW, belowId);
        lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);

        TextView tv = new TextView(this);
        tv.setId(id);

        tv.setText(text+"\n");
        rSub.addView(tv, lp);

    }

   class Proccess extends AsyncTask<Void, Void, Void>{

        @Override
        protected Void doInBackground(Void... arg0) {
            addTextView(R.id.tvResult, 1234, "s");
            return null;
        }
    }

5 个答案:

答案 0 :(得分:8)

使用此代码,它适用于我:

public class MainActivity extends Activity {

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            super.handleMessage(msg);
            TextView tvMain = (TextView) findViewById(R.id.tvMain);

                tvMain.setText(msg.getData().get("KEY")+"Button Proceed");
            }
        };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        /*Button btnDemo = (Button) findViewById(R.id.btnDemo);
        btnDemo.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                myAsyncTak();
            }


        });*/

        new AddTask().execute();
    }

    private void myAsyncTak() {
        // TODO Auto-generated method stub
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub

                TextView textView=new TextView(MainActivity.this);
                textView.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, 50));
                textView.setText("Newly Added TextView");
                View v=View.inflate(MainActivity.this, R.layout.activity_main, null);
                ((RelativeLayout)v).addView(textView);
                setContentView(v);

                Message msg=new Message();
                Bundle bundle=new Bundle();
                bundle.putString("KEY", "Saurabh");
                msg.setData(bundle);
                handler.sendMessage(msg);
                //handler.sendEmptyMessage(0);
            }
        };

        Thread myThread=new Thread(runnable);
        myThread.start();
    }
    public class AddTask extends AsyncTask<String, Integer, String>{

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params) {
            // TODO Auto-generated method stub
            myAsyncTak();
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
        }
    }


}

这个布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" 
    android:id="@+id/rlMain" >

    <TextView android:id="@+id/tvMain"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/btnDemo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvMain"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="42dp"
        android:text="Demo" />

</RelativeLayout>

答案 1 :(得分:4)

以类似

的方式运行UI线程
@Override
        protected Void doInBackground(Void... arg0) {
            this.runOnUiThread(new Runnable() {
            public void run() {
                addTextView(R.id.tvResult, 1234, "s");
        });
            return null;
        }

答案 2 :(得分:3)

UI工作应位于主线程中。

在android AsyncTask.doInBackground()中,顾名思义,它只适用于后台作业,如网络,数据库访问等。

您的方法addTextView()应位于AsyncTask.onPostExecute()

答案 3 :(得分:2)

您无法在doInBackground()中更改GUI 请尝试这样做,这样您就可以在UI线程中进行更改,同时仍然拥有doInBackground()中的代码:

@Override
    protected Void doInBackground(Void... arg0) {
       Runnable run = new Runnable() 
       {
            public void run() 
            {
                addTextView(R.id.tvResult, 1234, "s");
            }
    }; return null;
}

但请注意,涉及GUI更改的操作最好位于onPostExecute()onCreate()。无论如何,这是最好的做法:)

可能需要一段时间才能完成的操作,例如运行长数据库查询或应用程序可能被强制关闭的其他情况应位于doInBackground()

答案 4 :(得分:1)

您无法在TextView的{​​{1}}方法中添加doInBackground(),因为该方法在backgronud线程中运行,您无法在AsyncTask中执行操作,尝试在UI ThreadTextView

中添加onPreExecute()/onPostExecute()