Android知識總結

1.打開一個App, 從主頁跳轉到其深層子頁面,按HOME鍵回到桌面,再次打開,怎麼才能使再次打開看到的是主頁面?
(注:這個過程app並沒有被回收銷燬)

答:這個是通過配置主頁Activity在Manifest裏面的標籤屬性即可實現

 <activity android:name=".MainActivity"
    android:clearTaskOnLaunch="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
 </activity>

給主Activity添加屬性android:clearTaskOnLaunch = "true"即可實現

2.一個Activity的啓動模式是singleTop,如何實現像singleTask模式的啓動效果,即如果這個Activity不在這個任務棧中,創建一個新的實例,如果在這個任務棧中,無論是否在棧頂,都複用之前的實例,不再重新創建了,如果不在棧頂,則,把它上面的Activity出棧,把此Activity置於棧頂? (注:不要改變這個Activity啓動模式爲singleTask的前提下)

答:在啓動此Activity的時候,爲intent添加一個FLAG爲 Intent.FLAG_ACTIVITY_CLEAR_TOP 即可。

Intent i = new Intent(this,SecondActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

下面是Android源碼對 Intent.FLAG_ACTIVITY_CLEAR_TOP 的解釋

 If set, and the activity being launched is already running in the
 current task, then instead of launching a new instance of that     
 activity,all of the other activities on top of it will be closed 
 and this Intent will be delivered to the (now on top) old 
 activity as a new Intent.

 For example, consider a task consisting of the activities: A, 
 B, C, D.If D calls startActivity() with an Intent that resolves to 
 the component of activity B, then C and D will be finished and 
 B receive the given Intent, resulting in the stack now being: A, 
 B.The currently running instance of activity B in the above 
 example willeither receive the new intent you are starting here 
 in it onNewIntent() method, or be itself finished and restarted with the
 new intent.  If it has declared its launch mode to be "multiple" 
(thedefault) and you have not set {@link#FLAG_ACTIVITY_SINGLE_TOP} 
 in the same intent, then it will be finished and re-created; for 
all other launch modes or if {@link#FLAG_ACTIVITY_SINGLE_TOP} is set
 then this Intent will be delivered to the current instance 
onNewIntent(). 

This launch mode can also be used to good effect in 
conjunction with{@link#FLAG_ACTIVITY_NEW_TASK}:
if used to start the root activity of a task, it will bring any 
currently running instance of that  task to the foreground, and 
then clear it to its root state.  This is especially useful, for 
example, when launching an activity 
 from the notification manager.

如果設置這個屬性,並且這個activity已經在當前任務棧中運行,那麼就不會再在這個任務棧中爲這個activity創建一個新的實例,而是複用這個存在的實例,並且此Activity上面所有其他的activities都會被出棧,這個intent會被傳遞給這個被複用的activity實例。

例如:一個任務棧中有A、B、C、D四個activity,如果D通過包含此FLAG的Intent調起B,那麼C、D將會被 關閉掉,B會接收到這個intent,此時任務棧中只有A、B兩個activity了

在上面的例子中,這個正在運行的Activity B 將會通過onNewIntent()方法接收intent或者他自動關閉在重新啓動 , 如果Activity B的啓動模式是默認的,且設置的不是FLAG_ACTIVITY_SINGLE_TOP,那麼ActivityB會自動銷燬並且重啓,如果設置的是其他啓動模式或者是singleTop的話,Activity B將不會銷燬重建,而是被複用,通過onNewIntent();接收傳遞過來的intent。

這個啓動模式(Intent.FLAG_ACTIVITY_CLEAR_TOP)和(FLAG_ACTIVITY_NEW_TASK)一起使用將會起到很好的效果, 如果你想啓動某個根Activity,那麼它會把包含這個根Activity的任務棧放到前臺運行,並且會把這個任務棧中的根 Activity之上的其他activies都出棧,把此根activity置於棧頂。這是非常有用的,例如通過通知管理器啓動activity

3.如果連續多次啓動某個IntentService,會爲這個IntentService創建多個實例嗎,IntentService裏面的耗時操作是各自執行嗎?

答:首先看一下IntentService的官方解釋

IntentService is a base class for {@link Service}s that handle asynchronous
requests (expressed as {@link Intent}s) on demand. Clients send requests
through {@link android.content.Context#startService(Intent)} calls; the
service is started as needed, handles each Intent in turn using a worker
thread, and stops itself when it runs out of work.

This "work queue processor" pattern is commonly used to offload tasks
from an application's main thread. The IntentService class exists to
simplify this pattern and take care of the mechanics. To use it, extend
IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
will receive the Intents, launch a worker thread, and stop the service as
appropriate.

All requests are handled on a single worker thread -- they may take as
long as necessary (and will not block the application's main loop), but
only one request will be processed at a time.

意思就是IntentService可以處理異步請求,客戶端通過startService(Intent)發來請求,
IntentService相應的就會啓動,每個intent都會通過一個工作線程處理,並且任務執行
完之後,會自動結束掉

這種工作隊列處理器模式主要是用來處理主線程發來的卸載任務,IntentService的存在簡化
這種模式並且它比較關注的是運行機制。可以通過繼承IntentService並且實現onHandleIntent(Intent)
來使用它。IntentService收到Intent之後,會開啓一個工作線程,並且會在何時的時間自動關閉。

所有的請求都會交給一個異步線程處理,每個任務都會花費掉他們所需要長的時間來處理,但是不會阻塞
主線程,但是每次只能處理一個任務。
複製代碼
下面簡單看一下IntentService的源碼:

@Override
public void onCreate() {
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.

    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
 }

複製代碼
首先IntentService的onCreate()方法創建了一個HandlerThread並且啓動了它,並且把它持有的Looper給了
mServiceHandler,那麼mServiceHandler處理的就是這個子線程裏面的消息了 並且無論startService多少次,IntentServcie的onCreate()方法就執行一次,所以即便是有很多個任務,也只會
只有一個工作線程來處理。

@Override
public void onStart(@Nullable Intent intent, int startId) {
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

複製代碼
再來看IntentService的onStart()方法,它得到了一個message對象,並且把intent存儲在裏面,通過
mServiceHandler發送了出去,那麼這個message對象最終會被存儲到子線程的Queue中去,然後再通過
子線程的Looper.loo()方法取出,給mServiceHandler.handleMessage(Message)處理,這樣對Intent的處理
就從主線程轉移到了子線程,並且每調用startService(Intent)一次,onStart()方法就執行一次,這樣
接收到的Intent就會一次通過mServiceHandler發送到消息隊列裏面等待處理。

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1);
    }
}

@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);

複製代碼
如上所說:最終Intent通過mServiceHandler的handleMessage(Message)方法傳給了onHandleIntent(Intent)
來處理了,此時已經是在異步線程中了,如果有多個任務,都會存放到消息隊列裏面去,等待處理,但是始終只有
一個IntentServide實例,並且只有一個子線程來處理任務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章