1、簡介
該文記錄了本人在活動開發中遇到的諸多問題。現在開發中主要遇到的是,開發上的活動棧處理,以及一些主題設置相關的總結處理。
2、啓動模式
活動棧
主要分析下:SingleTop 和 singleTask 這2種啓動模式[當然一共有四種啓動模式:還包括singleInstance以及標準啓動 共計四種]
singleTop: 棧頂複用模式,如果新的Activity已經位於任務棧的棧頂,那麼此Activity不會被重新創建,同時它的 onNewIntent方法會被回調。
singleTask:棧內複用模式,這是一種單實例模式,在這種模式下,只要Activity在一個棧中存在,那麼多次啓動此Activity都不會重新創建實例,和singleTop一致,,系統也會回調onNewIntent。如果不存在,系統會先尋找是否存在需要的棧,如果不存在該棧,就創建一個任務棧,並把該Activity放進去;如果存在,就會創建到已經存在的棧中
singleTask用途: 同個Activity實例在棧中只有一個,即不存在重複創建;可通過android:taskAffinity設定該Activity需要的任務棧,即可能會引起任務棧的變更;常用於主頁和登陸頁
<activity
android:name=".improve.main.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:theme="@style/App.Theme.Main" />
代碼中設置的啓動模式要比xml中設置的啓動模式的優先級更高。
a-標準
標準模式 A-B-C-D-B-C 啓動過程結果如下所示
com.example.mydairytestproject E/Strand啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityD onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/Strand啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/Strand啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/Strand啓動模式: ActivityD onDestroy()
com.example.mydairytestproject E/Strand啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/Strand啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/Strand啓動模式: ActivityA onDestroy()
b-singleTop
在mainfest的活動中註冊!
<activity android:name=".task.ActivityB"
android:launchMode="singleTop"/>
當B C存在棧內但不位於棧頂是打印信息如下:
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityD onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityD onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onDestroy()
A-B-B是信息如下:
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onNewIntent
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onDestroy()
在代碼中書寫如下:
Intent intent = new Intent(ActivityB.this, ActivityB.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTop啓動模式: ActivityA onDestroy()
發現了吧,在對於棧頂複用模式,只能在xml中進行設定,那樣纔會new出一個實例,而調用標誌則只是先清除再重新創建罷了。
c-singleTask
A-B-C-D-B-C 效果如下
可以發現 D-B的過程中,位於B的棧上面的C,D都是先退出了。(棧內複用,但是位於其上的活動都結束了)
com.example.mydairytestproject E/SingleTask啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityD onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onNewIntent
com.example.mydairytestproject E/SingleTask啓動模式: ActivityD onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityA onDestroy()
java代碼中設置
Intent intent = new Intent(ActivityD.this, ActivityB.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
很帶怪,怎麼沒效果呢,我擦! 應該是任務棧不一樣。
com.example.mydairytestproject E/SingleTask啓動模式: ActivityA onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityD onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onCreate()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityD onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityC onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityB onDestroy()
com.example.mydairytestproject E/SingleTask啓動模式: ActivityA onDestroy()
拓展內容
下面針對手動設置flg做個小結
// 棧內複用,但是重新創建
12-02 14:16:07.004 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:16:10.505 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onCreate
12-02 14:16:12.850 19306-19306/com.example.mydairytestproject E/啓動模式: FLAG_ACTIVITY_CLEAR_TOP
12-02 14:16:12.892 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
12-02 14:16:12.917 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:16:13.281 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onDestroy
12-02 14:17:12.030 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
FLAG_ACTIVITY_CLEAR_TOP
清除包含目標 Activity 的任務棧中位於該 Activity 實例之上的其他 Activity 實例。 但是是複用已有的目標 Activity,還是先刪除後重建,則有以下規則:
-
若是使用 FLAG_ACTIVITY_SINGLE_TOP 和 FLAG_ACTIVITY_CLEAR_TOP 標誌位組合,那麼不管目標 Activity 是什麼啓動模式,都會被複用。
-
若是單獨使用 FLAG_ACTIVITY_CLEAR_TOP,那麼只有非 standard 啓動模式的目標 Activity 纔會被複用,否則都先被刪除,然後被重新創建併入棧。
// 這就是標準的 singletop模式
12-02 14:18:38.285 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:18:41.761 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onCreate
12-02 14:18:44.523 19306-19306/com.example.mydairytestproject E/啓動模式: FLAG_ACTIVITY_SINGLE_TOP
12-02 14:18:44.560 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:19:29.806 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
12-02 14:19:49.423 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onDestroy
12-02 14:20:01.384 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
// 結合起來纔是我們標準的singleInstance模式
12-02 14:20:44.454 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:20:45.711 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onCreate
12-02 14:20:47.058 19306-19306/com.example.mydairytestproject E/啓動模式: Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
12-02 14:20:47.083 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onNewIntent
12-02 14:20:47.417 19306-19306/com.example.mydairytestproject E/啓動模式: 活動B onDestroy
12-02 14:20:58.629 19306-19306/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TASK
標誌位組合啓動活動A 時,首先會清空活動A 所在的任務棧,然後再創建新的 IntentFlagTestActivity 實例併入棧
Intent intent = new Intent(LaunchBActivity.this,LaunchAActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
12-02 14:34:37.918 20378-20378/com.example.mydairytestproject E/啓動模式: MainActivity onCreate
12-02 14:34:45.389 20378-20378/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:34:46.565 20378-20378/com.example.mydairytestproject E/啓動模式: 活動B onCreate
12-02 14:35:04.262 20378-20378/com.example.mydairytestproject E/啓動模式: MainActivity onDestroy
12-02 14:35:04.299 20378-20378/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
12-02 14:35:04.332 20378-20378/com.example.mydairytestproject E/啓動模式: 活動A onCreate
12-02 14:35:04.625 20378-20378/com.example.mydairytestproject E/啓動模式: 活動B onDestroy
12-02 14:35:26.170 20378-20378/com.example.mydairytestproject E/啓動模式: 活動A onDestroy
FLAG_ACTIVITY_NEW_TASK
Android Intent.FLAG_ACTIVITY_NEW_TASK的個人理解
當非Activity啓動活動時需要加入標誌 Intent.FLAG_ACTIVITY_NEW_TASK
contextImpl 內
@Override
public void startActivity(Intent intent, Bundle options) {
warnIfCallingFromSystemProcess();
if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
throw new AndroidRuntimeException(
"Calling startActivity() from outside of an Activity "
+ " context requires the FLAG_ACTIVITY_NEW_TASK flag."
+ " Is this really what you want?");
}
mMainThread.getInstrumentation().execStartActivity(
getOuterContext(), mMainThread.getApplicationThread(), null,
(Activity) null, intent, -1, options);
}
Activity 內
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
跨應用調用活動
public void openOtherActivity(View view) {
Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.zxl","com.zxl.MainActivity");
intent.setComponent(componentName);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
Intent launchIntent = getPackageManager().getLaunchIntentForPackage("com.example.mydairytestproject");
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchIntent.setClassName("com.example.apple.scrolldemo","com.example.apple.scrolldemo.MainActivity");
startActivity(launchIntent);
3. 意圖以及匹配
至於顯式的意圖比較常見,就不在累贅了,這裏主要想提及以下隱式的意圖。IntentFilter中的過濾信息有action category和data。匹配時需要完全匹配這三者,一個過濾列表中,action category data可以有多個。一個intent只要能匹配一組filter那麼就能夠執行跳轉。下面將通過案例來進行解釋。
案例1
描述:只有一組intent-filter 且action,categoty,data 各一個,只是我們全匹配,發現跳轉正確。當缺少任何一個過濾即發生崩潰。
<activity android:name=".LocationActivity">
<!-- 案例1-->
<intent-filter >
<action android:name="com.zxl.location" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
void jumpToLocationAvy(){
Intent intent = new Intent();
intent.setAction("com.zxl.location");
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 類型----
intent.setType("text/plain");
startActivity(intent);
}
// 結果
E/IntentFtActivity: 執行跳轉
E/LocationActivity: onStart: 活動跳轉進來了
案例2
在案例1的基礎上在 filter多增加一個action,其餘條件不變,再次運行,運行正常。
<activity android:name=".LocationActivity">
<!--案例2-->
<intent-filter >
<action android:name="com.zxl.test"/>
<action android:name="com.zxl.location" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
案例3
如下所示,多增加了一個案例,發現失敗了。這裏不是應該匹配了下一個嘛。不要着急接着往下看
<activity android:name=".LocationActivity">
<!--案例3-->
<intent-filter >
<action android:name="com.zxl.test"/>
<action android:name="com.zxl.location" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>
<action android:name="com.zxl.filter"/>
</intent-filter>
</activity>
void jumpToLocationAvy(){
Intent intent = new Intent();
intent.setAction("com.zxl.filter");
startActivity(intent);
}
// ---------系統崩潰----------
案例4
在filter增加一個category就可以了,哈哈,機智啊。
<activity android:name=".LocationActivity">
<!--案例4-->
<intent-filter >
<action android:name="com.zxl.test"/>
<action android:name="com.zxl.location" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>
<action android:name="com.zxl.filter"/>
<!--*******重點******-->
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
// 下面可加可不加 默認就是這個
//intent.addCategory(Intent.CATEGORY_DEFAULT);
案例5
又增加一個 category發現也是運行正確
<activity android:name=".LocationActivity">
<!--案例5-->
<intent-filter >
<action android:name="com.zxl.test"/>
<action android:name="com.zxl.location" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
<intent-filter>
<action android:name="com.zxl.filter"/>
<category android:name="android.intent.category.DEFAULT" />
<!-- 又增加一個category-->
<category android:name="com.zxl.category"/>
</intent-filter>
</activity>
4. 其他使用技巧
/**
* 主界面按返回鍵不退出 而是位於後臺
* 這時候應用進來還是位於當前界面,而不會重新啓動
* @param keyCode
* @param event
* @return
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
moveTaskToBack(false);
return true;
}
return super.onKeyDown(keyCode, event);
}
5. 關於生命週期
可以明確的是,A 啓動一個正常的B 應用的時候生命週期方法是這樣執行的,A onPause() -----> A onStop() 然後是B 的生命週期,緊接着回退活動,A的生命週期方法執行的是 A onRestart() ------> A onStart() ------> onResume(),之前我存在一個誤區,經測試 活動啓動一個Dialog 其實是不會回調生命週期的。
MainActivity 跳轉 => ActivityA 生命週期回調
2019-12-06 10:58:57.834 2063-2063/com.example.mydairytestproject E/啓動: MainActivity onPause:
2019-12-06 10:58:58.147 2063-2063/com.example.mydairytestproject E/啓動: ActivityA onCreate:
2019-12-06 10:58:58.155 2063-2063/com.example.mydairytestproject E/啓動: ActivityA onStart:
2019-12-06 10:58:58.157 2063-2063/com.example.mydairytestproject E/啓動: ActivityA onResume:
2019-12-06 10:58:58.886 2063-2063/com.example.mydairytestproject E/啓動: MainActivity onStop:
那特殊的情況啓動一個透明應用,生命週期略有不同,這一點相比大家都是知道的,我這裏也進行一一番驗證吧。A啓動一個透明應用的話, 那麼A 首先會執行 onPause() 方法,緊接着當A 回退時執行的是 onResume() 方法。
08-31 09:30:49.361 25312-25312/com.example.zxl.myworklearning E/生命週期: ---onPause()---
08-31 09:30:55.300 25312-25312/com.example.zxl.myworklearning E/生命週期: ---onResume()---
記錄下如何設置透明應用,需要在style里加入如下屬性
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsTranslucent">true</item>
onSaveInstanceState() 會在Activity被異常終止的情況下調用,調用在onStop()之前,通過bundle 可在onRestoreInstanceState( ) 和 onCreate( ) 方法中接收並處理,達到恢復活動的效果,onResoreInstanceState( ) 是在onStart( )之後調用的
android:configChanges = "orientation" : 代表的是不讓Activity在屏幕旋轉的時候重新創建,指定了該屬性後是不會重新創建活動的,但是會調用 onConfigChaned( )方法。
6. 活動啓動動畫
1. 默認效果
當正常啓動一個活動默認的動畫效果是右邊的活動從右到左進來,退出的時候從左往右回去
2. 如何不帶動畫效果的啓動一個活動呢
A. 使用theme主題
如下實例爲不帶任何效果啓動一個activity
// mainfest進行主題設置
<activity android:name=".TopViewActivity"
android:theme="@style/TopViewTheme">
</activity>
styles定義主題樣式
android:windowAnimationStyle 可針對應用於該theme的活動的上的切換動畫方式。
<style name="TopViewTheme" parent="AppTheme">
// 改變整個應用的切換方式
<item name="android:windowAnimationStyle">@style/ActivityAnimation</item>
</style>
<!--指定activity動畫-->
<style name="ActivityAnimation">
<item name="android:activityOpenEnterAnimation">@null</item>
<item name="android:activityOpenExitAnimation">@null</item>
<item name="android:activityCloseEnterAnimation">@null</item>
<item name="android:activityCloseExitAnimation">@null</item>
<item name="android:taskOpenEnterAnimation">@null</item>
<item name="android:taskOpenExitAnimation">@null</item>
<item name="android:taskCloseEnterAnimation">@null</item>
<item name="android:taskCloseExitAnimation">@null</item>
<item name="android:taskToFrontEnterAnimation">@null</item>
<item name="android:taskToFrontExitAnimation">@null</item>
<item name="android:taskToBackEnterAnimation">@null</item>
<item name="android:taskToBackExitAnimation">@null</item>
</style>
ok,如上就完成了如何不帶任何樣式啓動一個活動的例子。
不動神色的返回
overridePendingTransition 常用於優雅的對活動進行切換
public void overridePendingTransition(int enterAnim, int exitAnim) {
try {
ActivityManagerNative.getDefault().overridePendingTransition(
mToken, getPackageName(), enterAnim, exitAnim);
} catch (RemoteException e) {
}
}
對即將要退出棧的活動,重寫其finish方法,讓其退出時不執行任何動畫效果。
@Override
public void finish() {
super.finish();
overridePendingTransition(0,0);
}
7. ContextImpl
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"initializeJavaContextClassLoader");
initializeJavaContextClassLoader();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
// 後面會執行綁定的.....
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
if (!mActivityThread.mInstrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to instantiate application " + appClass
+ ": " + e.toString(), e);
}
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!instrumentation.onException(app, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
// Rewrite the R 'constants' for all library apks.
SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
final int N = packageIdentifiers.size();
for (int i = 0; i < N; i++) {
final int id = packageIdentifiers.keyAt(i);
if (id == 0x01 || id == 0x7f) {
continue;
}
rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return app;
}
Instrumentation
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
8. 頁面跳轉規則
startActivity(new Intent(LoadingActivity.this, MainActivity.class));
overridePendingTransition(R.anim.screen_zoom_in, R.anim.screen_zoom_out);
finish();
講述下頁面跳轉的原則,啓動一個活動,設置動畫。如果需要結束那麼執行finish。
切記 千萬不能先finish再進行跳轉,否則會出現抖現黑屏的問題。