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