Android使用DexClassLoader動態載入未安裝Apk

來源:互聯網
上載者:User

因項目要求需要做類似於維信或Q遊這樣外掛程式化的開發模式,在網上也查了很多資料整理了一下並記在這裡,可用兩種方式:

1. 通過後台安裝,由於預設的安裝是通過PackageInstallActivity介面去執行安裝的,此介面有一個Dialog和一個ProcessBar,不能更改,想做些手腳一直沒找到方法,所以有了下面這一出。

方法:反射出sdk中的隱匿類PackageInstaller類,然後調用安裝方法instatllBatch(String),

                  Class<?> clz = Class.forName("com.android.util.PackageInstaller");
                  Method method = clz.getMethod("instatllBatch");
                  method.invoke(clz, path);

           可惜的是添加許可權<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" />,這玩意兒是系統進程方可有許可權。最後結果就是沒有結果。

2. 不安裝apk,通過動態載入dex包中的類,也屬於通過反射的方式來然後手動的建立Activity。

注意:這種方式跟系統建立的Activity是不一樣的,沒有系統建立的Activity的特性。而且R也找不到(也就是說無法通過layout來畫UI).而且啟動並執行並不是Apk中的Activity,

        也就是說它已經沒有了Android中Activity的特性,它只是在主程式中Activity上畫Apk中Activity的View。

這是調用的Activity:

package com.beyondsoft.activity;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import dalvik.system.DexClassLoader;import android.app.Activity;import android.content.pm.PackageInfo;import android.os.Bundle;import android.util.Log;public class PlugActivity extends Activity {private Class mActivityClass;private Object mActivityInstance;Class localClass;private Object instance;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Bundle paramBundle = new Bundle();paramBundle.putBoolean("KEY_START_FROM_OTHER_ACTIVITY", true);paramBundle.putString("str", "PlugActivity");String dexpath = "/sdcard/FragmentProject.apk";String dexoutputpath = "/mnt/sdcard/";LoadAPK(paramBundle, dexpath, dexoutputpath);}@Overrideprotected void onStart() {super.onStart();Method start;try {start = localClass.getMethod("onStart");start.invoke(instance);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overrideprotected void onResume() {// TODO Auto-generated method stubsuper.onResume();Method resume;try {resume = localClass.getMethod("onResume");resume.invoke(instance);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overrideprotected void onPause() {super.onPause();Method pause;try {pause = localClass.getMethod("onPause");pause.invoke(instance);} catch (Exception e) {e.printStackTrace();}}@Overrideprotected void onStop() {super.onStop();try {Method stop = localClass.getMethod("onStop");stop.invoke(instance);} catch (Exception e) {e.printStackTrace();}}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();try {Method des = localClass.getMethod("onDestroy");des.invoke(instance);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void LoadAPK(Bundle paramBundle, String dexpath, String dexoutputpath) {ClassLoader localClassLoader = ClassLoader.getSystemClassLoader();DexClassLoader localDexClassLoader = new DexClassLoader(dexpath, dexoutputpath, null, localClassLoader);try {PackageInfo plocalObject = getPackageManager().getPackageArchiveInfo(dexpath, 1);if ((plocalObject.activities != null) && (plocalObject.activities.length > 0)) {String activityname = plocalObject.activities[0].name;Log.d("sys", "activityname = " + activityname);localClass = localDexClassLoader.loadClass(activityname);//結果:"com.example.fragmentproject.FristActivity"mActivityClass = localClass;Constructor localConstructor = localClass.getConstructor(new Class[] {});instance = localConstructor.newInstance(new Object[] {});Log.d("sys", "instance = " + instance);mActivityInstance = instance;Method des = localClass.getMethod("test");des.invoke(instance);Method localMethodSetActivity = localClass.getDeclaredMethod("setActivity", new Class[] { Activity.class });localMethodSetActivity.setAccessible(true);localMethodSetActivity.invoke(instance, new Object[] { this }); Method methodonCreate = localClass.getDeclaredMethod("onCreate", new Class[] { Bundle.class }); methodonCreate.setAccessible(true); methodonCreate.invoke(instance, paramBundle);}return;} catch (Exception ex) {ex.printStackTrace();}}}

這是被調用的Activity:

public class FristActivity extends Activity{private Button fragment;private Button listFragment;private Button controlFragment;private Button viewFlipper;private Button viewPager;private Activity otherActivity;public void test() {Log.i("sys", "測試方法執行了");}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); // 測試DexClassLoader 動態載入未安裝Apk中的類TextView t = new TextView(otherActivity);t.setText("我是測試");otherActivity.setContentView(t);// R.layout.frist_activity_mainLog.i("sys", "Fragment項目啟動了");}public void setActivity(Activity paramActivity) {Log.d("sys", "setActivity..." + paramActivity);this.otherActivity = paramActivity;}@Overridepublic void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);Log.i("sys", "OnSaveInstance被調了");}@Overridepublic void onStart() {Log.i("sys", "onStart被調了");// TODO Auto-generated method stubsuper.onStart();}@Overridepublic void onResume() {Log.i("sys", "onResume被調了");// TODO Auto-generated method stubsuper.onResume();}@Overridepublic void onPause() {Log.i("sys", "onPause被調了");// TODO Auto-generated method stubsuper.onPause();}@Overridepublic void onStop() {Log.i("sys", "onStop被調了");// TODO Auto-generated method stubsuper.onStop();}@Overrideprotected void onDestroy() {Log.i("sys", "onDestroy被調了");// TODO Auto-generated method stubsuper.onDestroy();}}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.