欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入Android線程的相關(guān)問題解惑

 更新時(shí)間:2013年05月21日 11:00:21   作者:  
本篇文章是對(duì)Android線程的相關(guān)問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
一個(gè)應(yīng)用只有一個(gè)線程
在默認(rèn)情況下,更確切的講一個(gè)進(jìn)程中只有一個(gè)線程,這跟其他語(yǔ)言,比如C/C++,Java等是一致。也就是說在Android應(yīng)用程序里面一個(gè)進(jìn)程只有一個(gè)線程,所有組件都運(yùn)行在一個(gè)線程里面!

當(dāng)應(yīng)用程序啟動(dòng)時(shí),系統(tǒng)會(huì)為其創(chuàng)建一個(gè)進(jìn)程,也會(huì)創(chuàng)建一個(gè)線程名字叫做main,所有其所屬組件的創(chuàng)建,系統(tǒng)事件的處理,系統(tǒng)的回調(diào)等一切應(yīng)用相關(guān)的事情都運(yùn)行在此名叫main的線程中。此線程即為常說的主線程(main thread)。俗稱的UI線程(UI thread)也是它,因?yàn)橹挥兄骶€程可以操作UI相關(guān)的事情,所以有人把主線程也稱作UI線程,但這并不是正確的說法,因?yàn)镾ervice所屬的線程也可以操作Toast,但是Service并沒有UI。為什么非主線程不能操作UI呢?因?yàn)閷?duì)UI操作常常會(huì)引發(fā)系統(tǒng)的回調(diào),所以如果允許第三線程來操作可能會(huì)引發(fā)系統(tǒng)回調(diào)的紊亂,進(jìn)而會(huì)打亂整個(gè)框架的時(shí)序!
這里要特別注意的就是同一個(gè)進(jìn)程中的所有組件運(yùn)行在同一個(gè)線程中,Activiy,Service,BoradcastReceiver和ContentProvider都運(yùn)行在主線程中。

最容易引起誤解的就是Service,文檔和常識(shí)都會(huì)認(rèn)為Service是放在后臺(tái)用于操作費(fèi)時(shí)運(yùn)算的,但是實(shí)則不然,如果你在Service中做費(fèi)時(shí)操作,同樣會(huì)引發(fā)臭名昭著的ANR(Application Not Responding)。所以如果想把Service當(dāng)做一個(gè)Server,必須在Service用HandlerThread或Thread創(chuàng)建一個(gè)Worker線程!
Activity也是一樣的,你startActivity()后,開啟了一個(gè)新的Activity,但它們都運(yùn)行在同一個(gè)線程中,所以你還是不能在原Activity中做費(fèi)時(shí)操作!也即在調(diào)用startActivity()開啟了一個(gè)新的Activity后,或者在onPause(), onStop(), onDestroy()中做費(fèi)時(shí)操作會(huì)引發(fā)ANR。

對(duì)于ContentProvider也是一樣的,如果跟其他組件在同一進(jìn)程內(nèi),那么調(diào)用ContentResolver的方法會(huì)相當(dāng)于直接調(diào)用ContentProvider的方法。如果是在另外一個(gè)進(jìn)程中,雖是通過IPC,但也是同步的,因?yàn)镮Binder的同步的,也即調(diào)用ContentResolver時(shí)會(huì)把調(diào)用者的進(jìn)程掛起,等待ContentProvider的進(jìn)程操作結(jié)束,再把結(jié)果傳給調(diào)用者進(jìn)程!所以,如果ContentProvider中有費(fèi)時(shí)操作,或者會(huì)同步鎖數(shù)據(jù)庫(kù)等,也一定要注意ANR的發(fā)生!
所以一定要記住:一個(gè)進(jìn)程只有一個(gè)線程,所有組件都運(yùn)行在主線程中。
因此,如果有費(fèi)時(shí)操作,必須要?jiǎng)?chuàng)建Worker線程!

實(shí)例
下面有一個(gè)小實(shí)例,一個(gè)應(yīng)用中有五個(gè)組件:2個(gè)Activity,一個(gè)Service,一個(gè)ContentProvider和一個(gè)BroadcastReceiver。在每個(gè)組件的方法中都有打印所屬線程信息,另外對(duì)于Activity,Service和ContentProvider如果做費(fèi)時(shí)操作會(huì)引發(fā)ANR,對(duì)于BroadcastReceiver更是如此,這個(gè)大家都懂得的!
復(fù)制代碼 代碼如下:

public class ActivityDemo extends Activity {
    private static final String TAG = "ActivityDemo";
    private Handler mMainHandler = new Handler(new Handler.Callback() {
 public boolean handleMessage(Message msg) {
     dumpThreadInfo();
     return false;
 }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
 dumpThreadInfo();
 super.onCreate(savedInstanceState);

 // add four buttons
 LinearLayout layout = new LinearLayout(getApplication());
 layout.setOrientation(LinearLayout.VERTICAL);
 Button startService = new Button(getApplication());
 startService.setText("Start a Service");
 startService.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
  Intent i = new Intent(getApplication(), ServiceDemo.class);
  startService(i);
     }
 });
 layout.addView(startService);
 Button startAnother = new Button(getApplication());
 startAnother.setText("Start another Activity");
 startAnother.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
  Intent i = new Intent(getApplication(), AnotherActivity.class);
  startService(i);
     }
 });
 layout.addView(startAnother);
 Button startContentProvider = new Button(getApplication());
 startContentProvider.setText("Start a ContentProvider");
 startContentProvider.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
  getContentResolver().query(ContentProviderDemo.CONTENT_URI, null, null, null, null);
     }
 });
 layout.addView(startContentProvider);
 Button startReceiver = new Button(getApplication());
 startReceiver.setText("Start a BroadcastReceiver");
 startReceiver.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
  Intent i = new Intent("android.action.start_broadcastreceiver_demo");
  sendBroadcast(i);
     }
 });
 layout.addView(startReceiver);
 setContentView(layout);

 mMainHandler.sendEmptyMessageDelayed(0, 500);
    }

    public void dumpThreadInfo() {
 Thread.dumpStack();
 Log.e(TAG, Thread.currentThread().toString());
 Log.e(TAG, " " + getMainLooper());
    }
}

復(fù)制代碼 代碼如下:

public class AnotherActivity extends Activity {
    private static final String TAG = "AnotherActivity";
    private Handler mMainHandler = new Handler(getMainLooper(), new Handler.Callback() {
        public boolean handleMessage(Message msg) {
            // this will cause ANR
            Log.e(TAG, "you know what this is very slow slow slow slow");
            SystemClock.sleep(20 * 1000);
            dumpThreadInfo();
            return false;
        }
    });
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 dumpThreadInfo();
 super.onCreate(savedInstanceState);

 setTitle("this is another activity");
 mMainHandler.sendEmptyMessageDelayed(0, 500);
    }
    @Override
    protected void onDestroy() {
 dumpThreadInfo();
 super.onDestroy();
    }
    public void dumpThreadInfo() {
 Thread.dumpStack();
 Log.e(TAG, Thread.currentThread().toString());
 Log.e(TAG, " " + getMainLooper());
    }
}

復(fù)制代碼 代碼如下:

public class ServiceDemo extends Service {
    private Handler mMainHandler = new Handler(new Handler.Callback() {
        public boolean handleMessage(Message msg) {
            // this will cause ANR, too
            Log.e(TAG, "this is very slow you know, slow slow");
            SystemClock.sleep(20 * 1000);
            dumpThreadInfo();
            return false;
        }
    });
    private static final String TAG = "ServiceDemo";
    @Override
    public IBinder onBind(Intent arg0) {
 dumpThreadInfo();
 return null;
    }
    @Override
    public void onCreate() {
 dumpThreadInfo();
 super.onCreate();
 mMainHandler.sendEmptyMessageDelayed(0, 500);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
 dumpThreadInfo();
 return super.onStartCommand(intent, flags, startId);
    }

    public void dumpThreadInfo() {
 Thread.dumpStack();
 Log.e(TAG, Thread.currentThread().toString());
 Log.e(TAG, " " + getMainLooper());
    }
}

復(fù)制代碼 代碼如下:

public class ContentProviderDemo extends ContentProvider {
    public static final Uri CONTENT_URI = Uri.parse("content://com.hilton.effectiveandroid.app/content");
    private static final String TAG = "ContentProviderDemo";
    @Override
    public int delete(Uri arg0, String arg1, String[] arg2) {
 dumpThreadInfo();
 return 0;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
 dumpThreadInfo();
 return null;
    }
    @Override
    public boolean onCreate() {
 dumpThreadInfo();
 return false;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
 dumpThreadInfo();
 // it will cause ANR of course
 Log.e(TAG, "this is very slow, you know that");
 SystemClock.sleep(20 * 1000);
 return null;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
 dumpThreadInfo();
 return 0;
    }

    public void dumpThreadInfo() {
 Thread.dumpStack();
 Log.e(TAG, Thread.currentThread().toString());
    }
    @Override
    public String getType(Uri arg0) {
 return null;
    }
}

復(fù)制代碼 代碼如下:

public class BroadcastReceiverDemo extends BroadcastReceiver {
    private static final String TAG = "BroadcastReceiverDemo";
    @Override
    public void onReceive(Context context, Intent intent) {
 Log.e(TAG, "intent is " + intent);
 dumpThreadInfo();
    }

    public void dumpThreadInfo() {
 Thread.dumpStack();
 Log.e(TAG, Thread.currentThread().toString());
    }
}

相關(guān)文章

最新評(píng)論