Android中有些比较耗时的东西不能放在UI线程里面,因为当时间超过一段时间(大概5秒),就会出现ANR(Application No Response)错误。所以一些比较耗时的操作,例如联网或者读取一个比较大的文件里面的内容的时候这样才能出现错误。当然,还有其他的规定,Android中对控件的更新只能在UI线程里面(因为Android的设计直接在子线程里面更新控件是不安全的)。
实现异步处理的两种方式:
1.Handler(每个Handler实例都会绑定到创建他的线程中去)
先说说我的理解吧,我感觉Handler主要是将子线程的消息传过来,然后在Handler里面的更新。
所以可能是将耗时的操作放在了子线程中,然后处理完以后将信息传给Handler。
从子线程中将消息发送给主线程的方法有很多中。
一个小例子:
package zf.ui;
import com.example.android_handler.R;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView text;
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// Handler接收数据,然后更新
// TODO Auto-generated method stub
if(msg.what==1)
Toast.makeText(MainActivity.this, "gdd", Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
text = (TextView) findViewById(R.id.text);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
// 在子线程中处理比较复杂的事件,然后将信息(包含一些需要更新的信息)
// 传给handler,然后在Handler中处理数据
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
}).start();
}
}
2.AsyncTask
AsyncTask<Params, Progress, Result>,将比较耗时的操作放在doInBackground(Params...params)中,处理完以后在onPostExecute(Result result)更新。
package zf.ui;
import com.example.android_asynctask.R;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
text = (TextView)findViewById(R.id.text);
new AsyncTask<Object, Object, Object>() {
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
// 在doInBackground中处理比较复杂的事件
int n = (Integer)params[0];
long result = fib(n);
return result;
}
@Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
// 在UI线程中对其更新
super.onPostExecute(result);
text.setText(""+result.toString());
}
}.execute(50); // 调用execute()方法,运行。
}
public static long fib(int n){
if(n==1 || n==0)
return 1;
return fib(n-1)+fib(n-2);
}
}
还有很多不完善的地方,有待深究。