user2536596
user2536596

Reputation:

add view (text view) in AsyncTask

I used below code for add text view in Async task but :

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

How can i fixed this?

Code:

   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;
        }
    }

Upvotes: 3

Views: 5376

Answers (5)

Saurabh Android
Saurabh Android

Reputation: 668

Use this code , its working for me:

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);
        }
    }


}

And this layout:

<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>

Upvotes: 8

ClaireG
ClaireG

Reputation: 1244

You cannot make changes to the GUI in doInBackground() Try this instead so you can make the changes on the UI Thread while still having the code in doInBackground():

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

Please note, however, that operations that involve changes in the GUI should preferably be located in either onPostExecute() or in the onCreate(). That is the best practice, anyway :)

Operations that may take time to be completed, such as running long database queries or other situations where the application may be forced closed should be located in the doInBackground()

Upvotes: 2

Intae Kim
Intae Kim

Reputation: 309

UI works should locate in main thread.

In android AsyncTask.doInBackground(), as its name suggests, ONLY works with background jobs such as networking, db access, etc.

Your method addTextView() should locate in AsyncTask.onPostExecute()

Upvotes: 3

Sunil Kumar
Sunil Kumar

Reputation: 7092

run the UI thread in background method like that

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

Upvotes: 4

Onur A.
Onur A.

Reputation: 3017

You can't add TextView in doInBackground() method of AsyncTask, because that method operates in backgronud thread and you can't do operations rather than in UI Thread, try to add that TextView in onPreExecute()/onPostExecute() or out of doInBackground()

Upvotes: 1

Related Questions