a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

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

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

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

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

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

實例
下面有一個小實例,一個應(yīng)用中有五個組件:2個Activity,一個Service,一個ContentProvider和一個BroadcastReceiver。在每個組件的方法中都有打印所屬線程信息,另外對于Activity,Service和ContentProvider如果做費時操作會引發(fā)ANR,對于BroadcastReceiver更是如此,這個大家都懂得的!
復(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());
    }
}

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 久久最新| 国产精品九九九 | 精品欧美乱码久久久久久 | 欧美猛交ⅹxxx乱大交视频 | 日韩在线一 | 久草在线在线精品观看 | 欧洲精品久久久 | 欧美高清成人 | 亚洲综合无码一区二区 | 国产精品久久久久久久午夜片 | 黄色av网站在线免费观看 | 99精品国产在热久久 | 久久毛片免费 | 嗯嗯嗯亚洲精品国产精品一区 | 国产精品免费观看 | 日本视频在线免费观看 | 91免费看 | 亚洲视频免费在线观看 | 久久精品99国产精品亚洲最刺激 | 亚洲欧美在线观看 | 久久综合久色欧美综合狠狠 | 欧美性吧 | www.一区| 国产精品美女视频免费观看软件 | 成人在线观看亚洲 | 日日骑夜夜操 | 久久另类ts人妖一区二区 | 四色永久| 一区二区在线视频 | 国产不卡免费 | 九色社区 | 成人免费视频网站 | 精品国产欧美一区二区三区成人 | 欧产日产国产精品一二 | 国产精品一任线免费观看 | 国产精品久久久久久久久久久久久久 | www.亚洲 | 91av导航| 国产超碰人人模人人爽人人添 | 99视频精品| 精品美女在线 |