麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Android > 正文

深入Android線程的相關問題解惑

2020-04-11 12:23:11
字體:
來源:轉載
供稿:網友
一個應用只有一個線程
在默認情況下,更確切的講一個進程中只有一個線程,這跟其他語言,比如C/C++,Java等是一致。也就是說在Android應用程序里面一個進程只有一個線程,所有組件都運行在一個線程里面!

當應用程序啟動時,系統會為其創建一個進程,也會創建一個線程名字叫做main,所有其所屬組件的創建,系統事件的處理,系統的回調等一切應用相關的事情都運行在此名叫main的線程中。此線程即為常說的主線程(main thread)。俗稱的UI線程(UI thread)也是它,因為只有主線程可以操作UI相關的事情,所以有人把主線程也稱作UI線程,但這并不是正確的說法,因為Service所屬的線程也可以操作Toast,但是Service并沒有UI。為什么非主線程不能操作UI呢?因為對UI操作常常會引發系統的回調,所以如果允許第三線程來操作可能會引發系統回調的紊亂,進而會打亂整個框架的時序!
這里要特別注意的就是同一個進程中的所有組件運行在同一個線程中,Activiy,Service,BoradcastReceiver和ContentProvider都運行在主線程中。

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

對于ContentProvider也是一樣的,如果跟其他組件在同一進程內,那么調用ContentResolver的方法會相當于直接調用ContentProvider的方法。如果是在另外一個進程中,雖是通過IPC,但也是同步的,因為IBinder的同步的,也即調用ContentResolver時會把調用者的進程掛起,等待ContentProvider的進程操作結束,再把結果傳給調用者進程!所以,如果ContentProvider中有費時操作,或者會同步鎖數據庫等,也一定要注意ANR的發生!
所以一定要記住:一個進程只有一個線程,所有組件都運行在主線程中。
因此,如果有費時操作,必須要創建Worker線程!

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

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());
    }
}

復制代碼 代碼如下:

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());
    }
}

復制代碼 代碼如下:

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());
    }
}

復制代碼 代碼如下:

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;
    }
}

復制代碼 代碼如下:

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());
    }
}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 91在线播放国产 | h视频在线免费看 | 欧美a级在线免费观看 | 成年人黄视频 | 韩国三级日本三级香港三级黄 | 国产一级毛片视频在线! | 天堂成人一区二区三区 | 黄色网址在线播放 | 欧美a区| 国产超碰人人爽人人做人人爱 | 久久综合综合久久 | 天天草天天色 | 一级免费黄色免费片 | 国产乱淫a∨片免费观看 | 成人午夜久久 | 欧美日韩一 | 中文字幕亚洲视频 | 亚洲精品无码不卡在线播放he | 亚洲午夜影院在线观看 | 成人免费午夜视频 | 国内毛片视频 | 羞羞视频免费观看入口 | 日本在线免费观看视频 | 成人免费看视频 | 免费a网 | 色播视频网站 | 在线视频 日韩 | 一级做a爱片性色毛片高清 日本一区二区在线看 | 在线成人免费视频 | 国产高潮失禁喷水爽到抽搐视频 | 国产精品久久久久久久久久三级 | 亚洲日本韩国在线观看 | 亚州成人在线观看 | 嫩草影院在线观看网站成人 | 国产999在线| 爱高潮www亚洲精品 欧美黄色一级片视频 | 久久亚洲精品久久国产一区二区 | 国产乱一区二区三区视频 | 欧美成人激情在线 | 欧美成人小视频 | 日韩.www|