進程簡單的理解就是:啓動一個應用就是一個進程.每個應用有可能多個線程.如果一個android的主線程即main線程中執行了耗時操作,android系統可能會彈出ANR(Activity or App is not responding)對話框,嚴重影響了用戶體驗,會導致用戶不會再使用該應用軟件.ANR產生的條件是:
1) Activity中的事件執行超過5秒,操作沒有響應就會彈出ANR;
2) 廣播接收者onReceive()方法執行超過10秒,其他操作沒有響應也會彈出ANR
解決ANR的辦法就是在main線程中另起新線程來處理耗時操作:
例如:(部分代碼)
new Thread()
{
public void run()
{
// 模擬耗時操作
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
String result = "從網絡獲取的結果";
Message msg = new Message();
msg.what = 1;
msg.obj = result;
// 發送到main線程
mHandler.sendMessage(msg);
// textView.setText(result);
}
}.start();
雖然這可以解決ANR問題,但是如果在新線程中更新UI控件又會導致FC(force close),怎麼辦?android提供了runOnUiThread(new Runnable())方法,只有將更新UI的操作在這個方法裏執行,就可以使更新UI的事件放在main線程中執行,這樣就可以避免出現FC問題.例子代碼如下:
public class MainActivity extends Activity implements OnClickListener{
private TextView mTextView;
private TextView mTextView2;
Handler handler = new Handler()
{
public void handleMessage(Message msg)
{//這個方法裏面的代碼都是在main線程執行
Log.e("btn1OnClick", "ThreadName:" + Thread.currentThread().getName());
switch (msg.what) {
case 1:
String str2 = (String) msg.obj;
mTextView2.setText(str2);
break;
case 2:
String str1 = (String) msg.obj;
mTextView.setText(str1);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("onCreate", "ThreadName:" + Thread.currentThread().getName());
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
mTextView = (TextView) findViewById(R.id.textView1);
mTextView2 = (TextView) findViewById(R.id.textView2);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
btn1OnClick();
break;
case R.id.button2:
btn2OnClick();
break;
default:
break;
}
}
private void btn2OnClick() {
new Thread()
{
public void run()
{
Log.e("btn1OnClick", "ThreadName:" + Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String str = "從數據庫得到信息";
Message msg = new Message();
msg.what = 1;
msg.arg1 = 1;
msg.arg2 = 2;
msg.obj = str;
handler.sendMessage(msg );
};
}.start();
}
private void btn1OnClick() {
new Thread()
{
public void run()
{
Log.e("btn1OnClick", "ThreadName:" + Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String str = "從服務器得到信息";
Message msg = new Message();
msg.what = 2;
msg.arg1 = 1;
msg.arg2 = 2;
msg.obj = str;
handler.sendMessage(msg );
};
}.start();
}
}
以上通過handler來傳遞線程的信息,使更新的UI在main線程中執行,因此避免了FC問題.
聲明:以上如有問題可以聯繫:郵箱[email protected] 謝謝!