我使用下面的代码在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;
}
}
答案 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 Thread
或TextView
onPreExecute()/onPostExecute()