【Android開發學習筆記】【高級】【隨筆】插件化——Activity生命週期

前言java


  如同第一章咱們說的,宿主程序經過 dexclassloader 將插件的類加載進來,而後經過反射去調用它的方法,這樣Activity就被當成了一個普通的類來執行了,所以系統再也不接管它的生命週期,也就是說Activity的生命週期函數失效了。針對這樣的問題,有網友想出使用Fragment來解決此問題,Fragment既有相似於Activity的生命週期,又有相似於View的界面,所以選它比較合適,具體的作法是將Fragment加入到宿主的代理Activity內部,其生命週期將徹底由代理Activity來管理,固然採用這種方法的弊端就是:要求apk儘可能採用Fragment來實現,而且在頁面跳轉的時候比較麻煩,所以咱們這裏就放棄了這個作法,咱們依然經過反射的方法來作。 android

 

 

實現app


  咱們直接看實現吧。ide

  首先是在宿主工程的生命週期函數進行反射:函數

  1 package com.bryan.host;
  2 
  3 import java.io.File;
  4 import java.lang.reflect.Constructor;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.lang.reflect.Method;
  7 
  8 import dalvik.system.DexClassLoader;
  9 
 10 import android.annotation.SuppressLint;
 11 import android.app.Activity;
 12 import android.content.pm.PackageInfo;
 13 import android.content.pm.PackageManager;
 14 import android.content.res.AssetManager;
 15 import android.content.res.Resources;
 16 import android.content.res.Resources.Theme;
 17 import android.os.Bundle;
 18 import android.provider.MediaStore.Video;
 19 
 20 public class ProxyActivity extends Activity
 21 {
 22     /* 接收mainActivity傳來的*/
 23     ...
 24     
 25     /* classloder來的object*/
 26     ...
 27     
 28     /* 用來加載資源的*/
 29     ...
 30     
 31     @Override
 32     protected void onCreate(Bundle savedInstanceState) 
 33     {
 34         super.onCreate(savedInstanceState);
 35         
 36         ....
 37     }
 38     
 39     /* 加載插件的主activity*/
 40     protected void OpenDefaultActivity()
 41     {
 42         ...
 43     }
 44     
 45     /* 加載插件的指定activity*/
 46     @SuppressLint("NewApi") protected void OpenAppointActivity(final String className)
 47     {
 48         ...
 49     }
 50     
 51     
 52     protected void loadResources()
 53     {
 54         ...
 55     }    
 56     
 57     /* 重寫這兩個加載資源的函數 */
 58     ....
 59 
 60     
 61     /* 反射其餘生命週期函數 */
 62     @Override
 63     protected void onStart() {
 64         super.onStart();
 65         ReflectOnFunction("onStart");        
 66     }
 67 
 68     @Override
 69     protected void onResume() {        
 70         super.onResume();    
 71         ReflectOnFunction("onResume");    
 72     }
 73 
 74     @Override
 75     protected void onPause() {
 76         super.onPause();
 77         ReflectOnFunction("onPause");    
 78     }
 79 
 80     @Override
 81     protected void onStop() {        
 82         super.onStop();
 83         ReflectOnFunction("onStop");    
 84     }
 85 
 86     @Override
 87     protected void onDestroy() {        
 88         super.onDestroy();
 89         ReflectOnFunction("onDestroy");    
 90     }  
 91     
 92     private void ReflectOnFunction(String FunctionName)
 93     {
 94         Method onFunction;
 95         try 
 96         {
 97             onFunction = mlocaClass.getDeclaredMethod(FunctionName, new Class[] {});
 98             onFunction.setAccessible(true);        
 99             onFunction.invoke(mobject);      
100         } catch (NoSuchMethodException e) {
101             e.printStackTrace();
102         } catch (IllegalAccessException e) {
103             e.printStackTrace();
104         } catch (IllegalArgumentException e) {
105             e.printStackTrace();
106         } catch (InvocationTargetException e) {
107             e.printStackTrace();
108         }
109     }
110 }

  插件工程中,咱們能夠直接在實際看到的Activity中直接加入反射,修改代碼,也能夠在BaseActivity中進行完成(這裏我選了後者),爲了看起來統一:、佈局

 1 package com.bryan.plugin;
 2 
 3 import android.app.Activity;
 4 import android.content.Intent;
 5 import android.content.res.AssetManager;
 6 import android.content.res.Resources;
 7 import android.os.Bundle;
 8 import android.view.View;
 9 import android.view.ViewGroup.LayoutParams;
10 
11 public class BaseActivity extends Activity
12 {
13     /* 宿主工程中的代理Activity*/
14     protected Activity mProxyActivity;
15     
16     /* 判斷是被誰調起的,若是是宿主調起的爲1 */
17     int Who = 0;
18     
19     public void setProxy(Activity proxyActivity)
20     {
21         mProxyActivity = proxyActivity;
22     }
23     
24     @Override
25     protected void onCreate(Bundle savedInstanceState) 
26     {    
27         ...
28     }    
29     
30     ......
31 
32     @Override
33     protected void onResume() {
34         if (mProxyActivity == this) 
35             super.onResume();
36     }
37 
38     @Override
39     protected void onPause() {
40         if (mProxyActivity == this) 
41             super.onPause();
42     }
43 
44     @Override
45     protected void onStop() {
46         if (mProxyActivity == this) 
47             super.onStop();
48     }
49 
50     @Override
51     protected void onDestroy() {
52         if (mProxyActivity == this) 
53             super.onDestroy();
54     }    
55 }

  插件的實際看到的類中直接重寫這些方法,維持默認的狀態就能夠了:測試

 1 package com.bryan.plugin;
 2 
 3 import android.content.Context;
 4 import android.graphics.Color;
 5 import android.graphics.drawable.BitmapDrawable;
 6 import android.os.Bundle;
 7 import android.view.View;
 8 import android.view.View.OnClickListener;
 9 import android.view.ViewGroup.LayoutParams;
10 import android.widget.Button;
11 import android.widget.ImageView;
12 import android.widget.LinearLayout;
13 
14 public class MainActivity extends BaseActivity {
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);      
19         
20         // 初始化處理佈局
21         InitView();
22     }
23     
24     .....
25     
26     @Override
27     protected void onStart() {
28         super.onStart();
29         PluginLog.pluginLog("onStart"); 
30     }
31 
32     @Override
33     protected void onPause() {
34         super.onPause();    
35         PluginLog.pluginLog("onPause"); 
36     }
37 
38     @Override
39     protected void onResume() {
40         super.onResume();
41         PluginLog.pluginLog("onResume"); 
42     }
43 
44     @Override
45     protected void onStop() {
46         super.onStop();
47         PluginLog.pluginLog("onStop"); 
48     }
49 
50     @Override
51     protected void onDestroy() {
52         super.onDestroy();
53         PluginLog.pluginLog("onDestroy"); 
54     }   
55 }

  代碼中的 pluginLog 只是我本身打log用的,沒必要關係它的實現細節。優化

 

 

結果this


   在宿主程序拉起App後在Logcat中能夠看到:spa

 

 

  到此爲止,一個相對完整的插件的化的例子就算是作完了,固然這裏面有不少能夠優化的地方,不過我完成這三篇文章的目的也就是對於插件化原理的一個簡單探索,讓想了解插件原理的人入個門。因爲本人是測試,不是開發出身,所以文章內不免會有寫錯誤的地方,但願你們能不吝賜教。

  點擊下載源代碼

相關文章
相關標籤/搜索