To build a better world !

          Android類動態(tài)加載技術(shù)

          轉(zhuǎn)載請注明出處:http://www.aygfsteel.com/zh-weir/archive/2011/10/29/362294.html 

          Android類動態(tài)加載技術(shù)

          Android應(yīng)用開發(fā)在一般情況下,常規(guī)的開發(fā)方式和代碼架構(gòu)就能滿足我們的普通需求。但是有些特殊問題,常常引發(fā)我們進(jìn)一步的沉思。我們從沉思中產(chǎn)生頓悟,從而產(chǎn)生新的技術(shù)形式。

          如何開發(fā)一個可以自定義控件的Android應(yīng)用?就像eclipse一樣,可以動態(tài)加載插件;如何讓Android應(yīng)用執(zhí)行服務(wù)器上的不可預(yù)知的代碼?如何對Android應(yīng)用加密,而只在執(zhí)行時自解密,從而防止被破解?……

          熟悉Java技術(shù)的朋友,可能意識到,我們需要使用類加載器靈活的加載執(zhí)行的類。這在Java里已經(jīng)算是一項(xiàng)比較成熟的技術(shù)了,但是在Android中,我們大多數(shù)人都還非常陌生。

          類加載機(jī)制

                 Dalvik虛擬機(jī)如同其他Java虛擬機(jī)一樣,在運(yùn)行程序時首先需要將對應(yīng)的類加載到內(nèi)存中。而在Java標(biāo)準(zhǔn)的虛擬機(jī)中,類加載可以從class文件中讀取,也可以是其他形式的二進(jìn)制流。因此,我們常常利用這一點(diǎn),在程序運(yùn)行時手動加載Class,從而達(dá)到代碼動態(tài)加載執(zhí)行的目的。

                 然而Dalvik虛擬機(jī)畢竟不算是標(biāo)準(zhǔn)的Java虛擬機(jī),因此在類加載機(jī)制上,它們有相同的地方,也有不同之處。我們必須區(qū)別對待。

                 例如,在使用標(biāo)準(zhǔn)Java虛擬機(jī)時,我們經(jīng)常自定義繼承自ClassLoader的類加載器。然后通過defineClass方法來從一個二進(jìn)制流中加載Class。然而,這在Android里是行不通的,大家就沒必要走彎路了。參看源碼我們知道,AndroidClassLoaderdefineClass方法具體是調(diào)用VMClassLoaderdefineClass本地靜態(tài)方法。而這個本地方法除了拋出一個“UnsupportedOperationException”之外,什么都沒做,甚至連返回值都為空。

          static void Dalvik_java_lang_VMClassLoader_defineClass(const u4* args,

              JValue
          * pResult)

          {

              Object
          * loader = (Object*) args[0];

              StringObject
          * nameObj = (StringObject*) args[1];

              
          const u1* data = (const u1*) args[2];

              
          int offset = args[3];

              
          int len = args[4];

              Object
          * pd = (Object*) args[5];

              
          char* name = NULL;

           

              name 
          = dvmCreateCstrFromString(nameObj);

              LOGE(
          "ERROR: defineClass(%p, %s, %p, %d, %d, %p)\n",

                  loader, name, data, offset, len, pd);

              dvmThrowException(
          "Ljava/lang/UnsupportedOperationException;",

                  
          "can't load this type of class file");

           

              free(name);

              RETURN_VOID();

          }


          Dalvik
          虛擬機(jī)類加載機(jī)制

                 那如果在Dalvik虛擬機(jī)里,ClassLoader不好使,我們?nèi)绾螌?shí)現(xiàn)動態(tài)加載類呢?Android為我們從ClassLoader派生出了兩個類:DexClassLoaderPathClassLoader。其中需要特別說明的是PathClassLoader中一段被注釋掉的代碼:

          /* --this doesn't work in current version of Dalvik--

              if (data != null) {

                  System.out.println("--- Found class " + name

                      + " in zip[" + i + "] '" + mZips[i].getName() + "'");

                  int dotIndex = name.lastIndexOf('.');

                  if (dotIndex != -1) {

                      String packageName = name.substring(0, dotIndex);

                      synchronized (this) {

                          Package packageObj = getPackage(packageName);

                          if (packageObj == null) {

                              definePackage(packageName, null, null,

                                      null, null, null, null, null);

                          }

                      }

                  }

           

                  return defineClass(name, data, 0, data.length);

              }

          */



                 這從另一方面佐證了defineClass函數(shù)在Dalvik虛擬機(jī)里確實(shí)是被閹割了。而在這兩個繼承自ClassLoader的類加載器,本質(zhì)上是重載了ClassLoaderfindClass方法。在執(zhí)行loadClass時,我們可以參看ClassLoader部分源碼:

          protected Class<?> loadClass(String className, boolean resolve) 

          throws ClassNotFoundException {

          Class
          <?> clazz = findLoadedClass(className);

           

              
          if (clazz == null{

                  
          try {

                      clazz 
          = parent.loadClass(className, false);

                  }
           catch (ClassNotFoundException e) {

                      
          // Don't want to see this.

                  }


           

                  
          if (clazz == null{

                      clazz 
          = findClass(className);

                  }


              }


           

              
          return clazz;

          }


                 因此DexClassLoaderPathClassLoader都屬于符合雙親委派模型的類加載器(因?yàn)樗鼈儧]有重載loadClass方法)。也就是說,它們在加載一個類之前,回去檢查自己以及自己以上的類加載器是否已經(jīng)加載了這個類。如果已經(jīng)加載過了,就會直接將之返回,而不會重復(fù)加載。

                 DexClassLoaderPathClassLoader其實(shí)都是通過DexFile這個類來實(shí)現(xiàn)類加載的。這里需要順便提一下的是,Dalvik虛擬機(jī)識別的是dex文件,而不是class文件。因此,我們供類加載的文件也只能是dex文件,或者包含有dex文件的.apk.jar文件。

                  
          也許有人想到,既然DexFile可以直接加載類,那么我們?yōu)槭裁催€要使用ClassLoader的子類呢?DexFile在加載類時,具體是調(diào)用成員方法loadClass或者loadClassBinaryName。其中loadClassBinaryName需要將包含包名的類名中的”.”轉(zhuǎn)換為”/”。我們看一下loadClass代碼就清楚了:


          public Class loadClass(String name, ClassLoader loader) {

                  String slashName 
          = name.replace('.''/');

                  
          return loadClassBinaryName(slashName, loader);

          }

                 在這段代碼前有一段注釋,截取關(guān)鍵一部分就是說:If you are not calling this from a class loader, this is most likely not going to do what you want. Use {@link Class#forName(String)} instead. 這就是我們需要使用ClassLoader子類的原因。至于它是如何驗(yàn)證是否是在ClassLoader中調(diào)用此方法的,我沒有研究,大家如果有興趣可以繼續(xù)深入下去。

                 有一個細(xì)節(jié),可能大家不容易注意到。PathClassLoader是通過構(gòu)造函數(shù)new DexFile(path)來產(chǎn)生DexFile對象的;而DexClassLoader則是通過其靜態(tài)方法loadDexpath, outpath, 0)得到DexFile對象。這兩者的區(qū)別在于DexClassLoader需要提供一個可寫的outpath路徑,用來釋放.apk包或者.jar包中的dex文件。換個說法來說,就是PathClassLoader不能主動從zip包中釋放出dex,因此只支持直接操作dex格式文件,或者已經(jīng)安裝的apk(因?yàn)橐呀?jīng)安裝的apkcache中存在緩存的dex文件)。而DexClassLoader可以支持.apk.jar.dex文件,并且會在指定的outpath路徑釋放出dex文件。

                 另外,PathClassLoader在加載類時調(diào)用的是DexFileloadClassBinaryName,而DexClassLoader調(diào)用的是loadClass。因此,在使用PathClassLoader時類全名需要用”/”替換”.”


          實(shí)際操作

                 這一部分比較簡單,因此我就不贅言了。只是簡單的說下。

                 可能使用到的工具都比較常規(guī):javacdxeclipse等。其中dx工具最好是指明--no-strict,因?yàn)?/span>class文件的路徑可能不匹配。

                 加載好類后,通常我們可以通過Java反射機(jī)制來使用這個類。但是這樣效率相對不高,而且老用反射代碼也比較復(fù)雜凌亂。更好的做法是定義一個interface,并將這個interface寫進(jìn)容器端。待加載的類,繼承自這個interface,并且有一個參數(shù)為空的構(gòu)造函數(shù),以使我們能夠通過ClassnewInstance方法產(chǎn)生對象。然后將對象強(qiáng)制轉(zhuǎn)換為interface對象,于是就可以直接調(diào)用成員方法了。


          關(guān)于代碼加密的一些設(shè)想

                 最初設(shè)想將dex文件加密,然后通過JNI將解密代碼寫在Native層。解密之后直接傳上二進(jìn)制流,再通過defineClass將類加載到內(nèi)存中。

                 現(xiàn)在也可以這樣做,但是由于不能直接使用defineClass,而必須傳文件路徑給dalvik虛擬機(jī)內(nèi)核,因此解密后的文件需要寫到磁盤上,增加了被破解的風(fēng)險。

                 Dalvik虛擬機(jī)內(nèi)核僅支持從dex文件加載類的方式是不靈活的,由于沒有非常深入的研究內(nèi)核,我不能確定是Dalvik虛擬機(jī)本身不支持還是Android在移植時將其閹割了。不過相信Dalvik或者是Android開源項(xiàng)目都正在向能夠支持raw數(shù)據(jù)定義類方向努力。

                 我們可以在文檔中看到Google說:Jar or APK file with "classes.dex". (May expand this to include "raw DEX" in the future.);在AndroidDalvik源碼中我們也能看到RawDexFile的身影(不過沒有具體實(shí)現(xiàn))。

                 RawDexFile出來之前,我們都只能使用這種存在一定風(fēng)險的加密方式。需要注意釋放的dex文件路徑及權(quán)限管理,另外,在加載完畢類之后,除非出于其他目的否則應(yīng)該馬上刪除臨時的解密文件。


          轉(zhuǎn)載請注明出處:http://www.aygfsteel.com/zh-weir/archive/2011/10/29/362294.html 

          posted on 2011-10-29 21:51 zh.weir 閱讀(37958) 評論(25)  編輯  收藏 所屬分類: Android軟件安全

          評論

          # re: Android類動態(tài)加載技術(shù) 2011-11-30 13:25 android動態(tài)加載

          更好的做法是定義一個interface,并將這個interface寫進(jìn)容器端
          >容器端做interface的強(qiáng)制類型轉(zhuǎn)換時出現(xiàn)異常,java.lang.ClassCastException:
          不知道您有沒有遇到?  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2011-11-30 20:52 zh-weir


          檢查一下,是否在Host端和Plugin端分別都定義了liangzijian這個接口。如果都定義了,且均被編譯進(jìn)了字節(jié)碼文件中就會發(fā)生類似的問題。原因是 newInstance生成的對象實(shí)現(xiàn)的是Plugin端的liangzijian接口,而你想要轉(zhuǎn)化的是Host端的liangzijian接口。兩個接口雖然名字相同,甚至可能包名也一樣,但是它們是由不同的類加載器加載的,所以不同不能實(shí)現(xiàn)轉(zhuǎn)化。

          解決辦法是不要將liangzijian接口編譯進(jìn)Plugin端的字節(jié)碼中。具體做法是導(dǎo)入liangzijian接口的jar庫時,不要使用添加外部jar庫,而應(yīng)使用user library。后一種方式不會將庫中的類編譯進(jìn)字節(jié)碼中,而是在運(yùn)行時去動態(tài)鏈接。
            回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2011-12-01 15:15 android動態(tài)加載

          @zh-weir
          問題解決了,需要注意兩點(diǎn):
          1、Host端和Plugin端interface文件的包名需要一致
          2、jar文件打包時不要包含interface文件

          另外,DexClassLoader的最后一個參數(shù)使用getClassLoader()或者VMStack.getCallingClassLoader();  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2011-12-02 10:31 zephyranthes

          有點(diǎn)問題想請教樓主,之前使用dexclassloader想加載另一個apk的activity會出現(xiàn)activitynotfoundexception異常,似乎這種方式行不通.

          后來想到是不時只是寫一個jni的native activity,當(dāng)apk運(yùn)行時,會先運(yùn)行這個jni so,然后該so生成解密的dex文件,再通過dexclassloader加載該dex中的activity?

          麻煩樓主解答,謝謝  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-02-17 23:59 passbye

          反復(fù)反復(fù)反復(fù)反復(fù)反復(fù)反復(fù)反復(fù)反復(fù)反復(fù)  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-02-18 00:01 pass

          請問對于(對Android應(yīng)用加密,而只在執(zhí)行時自解密,從而防止被破解?)這句話該如何理解,是對本地的(已安裝好的)apk加密還是什么操作?請大家指教。謝謝,希望大家共同進(jìn)步。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-02-28 09:19 zh_weir

          @pass

          由于apk應(yīng)用需要經(jīng)過Android系統(tǒng)的解析和安裝,因此是不能對它進(jìn)行直接加密的哦。那樣會導(dǎo)致apk無法安裝或者無法運(yùn)行。

          我的意思是將核心代碼抽取出來,作為二進(jìn)制資源,由APK應(yīng)用在運(yùn)行時動態(tài)加載。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-08 20:05 林風(fēng)

          @android動態(tài)加載
          可否留個郵箱,交流一下,My Email --xk1411@139.com.  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-09 17:06 zh.weir

          @林風(fēng)

          呵呵,其實(shí)右上方的公告里有寫。zh.weir@gmail.com 。

          歡迎交流!  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 10:04 ljj

          小弟現(xiàn)正開發(fā)一個這樣一個應(yīng)用,這個應(yīng)用做為主應(yīng)用,只需要實(shí)現(xiàn)一些基本的功能就行,
          如果要擴(kuò)展功能的話,就通過開發(fā)一些小插件來實(shí)現(xiàn)

          實(shí)現(xiàn)原理是這樣的:
          主應(yīng)用(Host)定義一個接口:
          public abstract interface IExtension{
          void method1(WebView webview,....);
          void method2();


          public class AbstractExtension extends ContextWrapper implements IExtension{
          .....
          基本是對IExtension的空實(shí)現(xiàn)

          }


          這里應(yīng)用反射來實(shí)例化一個插件:
          ClassLoader localExtensionClassLoader = context.createPackageContext(this.mPackageName,Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY).getClassLoader();
          ClassLoader localSystemClassLoader = OlivePackageManager.getSystemClassLoader();

          ClassLoaderWrapper localClassLoaderWrapper = new ClassLoaderWrapper(localExtensionClassLoader, localSystemClassLoader);

          String localClassName = String.valueOf(this.mPackageName) + ".Extension";
          Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);

          Constructor<?> localConstructor = localClass.getConstructor( new Class[]{Context.class} );
          localConstructor.setAccessible(true);

          Object instance = localConstructor.newInstance( new Object[]{context} );




          public class ClassLoaderWrapper extends ClassLoader{

          public ClassLoaderWrapper(ClassLoader extensionClassLoader, ClassLoader systemClassLoader) {
          super(systemClassLoader);
          this.mLoader = extensionClassLoader;
          }

          protected Class<?> findClass(String className) throws ClassNotFoundException {
          System.out.println("mLoader type === " + mLoader.toString());
          Class<?> localClass = null;

          if (localClass == null){
          //這個地方,就是這個地方,加載失敗
          localClass = this.mLoader.loadClass(className);
          }

          System.out.println("mLoader.loadClass============="+localClass);
          return localClass;
          }

          protected Class<?> loadClass(String className, boolean paramBoolean){
          Class<?> localClass = null;
          try {
          localClass = getParent().loadClass(className);
          } catch (ClassNotFoundException localClassNotFoundException) {
          localClass = findLoadedClass(className);

          if (localClass == null) {
          try {
          localClass = findClass(className);
          } catch (ClassNotFoundException e) {
          }
          }
          }

          return localClass;
          }




          在插件工程中:
          public class Extension extends AbstractExtension{
          ...實(shí)現(xiàn)IExtension接口


          這樣做的話,插件工程必須加入對主工程(Host)的引用



          思想是好的,但是問題出來了,我主應(yīng)用的類加載器總是load不到插件工程的Extension類,
          但是如果我的插件工程里面不extends AbstractExtension 的話,是ok的,但是不繼承,就失去了意義。

          分析原因:
          public ClassLoaderWrapper(ClassLoader extensionClassLoader, ClassLoader systemClassLoader) {
          super(systemClassLoader);
          this.mLoader = extensionClassLoader;
          }
          這個構(gòu)造函數(shù)里面,extensionClassLoader作為父類加載器,extensionClassLoader作為插件的類加載器,

          loadClass方法里面,先用systemClassLoader加載,應(yīng)該是加載不到插件的Extension的,那么接下來就使用extensionClassLoader來加載,這個時候extensionClassLoader與插件的Extension是同一Context,理所當(dāng)然能夠加載到,但是問題是Extension extends AbstractExtension,它肯定是加載不到AbstractExtension,導(dǎo)致插件的Extension也加載失敗

          這個問題困擾了我多日了,希望哪位給個意見,幫助分析一下,我應(yīng)該怎么做?

            回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 15:09 zh-weir

          @ljj

          之前的評論有說:

          需要注意兩點(diǎn):
          1、Host端和Plugin端interface文件的包名需要一致
          2、jar文件打包時不要包含interface文件

          另外,DexClassLoader的最后一個參數(shù)使用getClassLoader()或者VMStack.getCallingClassLoader();  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 15:39 ljj

          樓主,我用的是自定的classloader,沒用DexClassLoader,我現(xiàn)在就是要動態(tài)加載插件的
          類Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);但是在自定義的classloader中的@Override
          protected Class<?> findClass(String className)
          throws ClassNotFoundException {
          System.out.println("mLoader type === " + mLoader.toString());
          Class<?> localClass = null;
          if ((this.mLoader instanceof PathClassLoader)){
          //localClass = a(paramString);

          }
          if (localClass == null) {
          // 這個地方,就是這個地方,加載失敗
          localClass = this.mLoader.loadClass(className);
          }

          System.out.println("mLoader.loadClass=============" + localClass);
          return localClass;
          }

          我沒有用到j(luò)ar包,謝謝  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 16:45 zh-weir

          @ljj

          沒有用到j(luò)ar,那你是從哪個文件里load類?這點(diǎn)需要明確。個人認(rèn)為,第一可能是沒有指明從哪個文件load類;第二是IExtension被不同的類加載器加載了兩次,這樣兩個IExtension雖然名字相同、包名相同,但是它們是不同的類。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 17:25 ljj

          @zh-weir

          我是要加載插件中的類

          String localClassName = String.valueOf(packageName)+ ".Extension";


          其中ClassLoaderWrapper 是自定義的classloader
          IExtension只在主host定義的接口
          在主host基本是對IExtension的空實(shí)現(xiàn)

          在插件中具體實(shí)現(xiàn)

          ClassLoaderWrapper localClassLoaderWrapper = new ClassLoaderWrapper (localExtensionClassLoader , localSystemClassLoader );
          String localClassName = String.valueOf(this.c)+ ".Extension";
          Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);


            回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-26 17:37 zh.weir

          @ljj

          String localClassName = String.valueOf(this.c)+ ".Extension";
          Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);

          這是load插件中的類嗎?你的“插件”存在于哪?是安裝好的apk,還是未安裝的apk,還是jar或者dex文件?總需要一個路徑的。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-27 08:17 ljj

          @zh-weir
          我的插件是已安裝好的apk,


          String localClassName = String.valueOf(this.c)+ ".Extension";
          Class<?> localClass = localClassLoaderWrapper.loadClass(localClassName);


          localClassName 是要去動態(tài)加載的插件中的類名,現(xiàn)在就是加載不上,
          自定義的classloader中

          @Override
          protected Class<?> findClass(String className)
          throws ClassNotFoundException {
          System.out.println("mLoader type === " + mLoader.toString());
          Class<?> localClass = null;
          if ((this.mLoader instanceof PathClassLoader)){
          //localClass = a(paramString);

          }
          if (localClass == null) {
          // 這個地方,就是這個地方,加載失敗
          localClass = this.mLoader.loadClass(className);
          }

          System.out.println("mLoader.loadClass=============" + localClass);
          return localClass;
          }  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-27 19:54 zh-weir

          又看了一下你的代碼。首先應(yīng)該是AbstractExtension這個類沒有加載到。這個類,理論上應(yīng)該是由Host端的類加載器加載好的。所以問題是,plugin端可能并沒有發(fā)現(xiàn)由host端加載好的AbstractExtension類。分析了可能的原因,覺得ClassLoader localSystemClassLoader = OlivePackageManager.getSystemClassLoader();這個Classloader可能并不是ClassLoader localExtensionClassLoader = context.createPackageContext(this.mPackageName,Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY).getClassLoader(); 這個ClassLoader的parent……  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-27 20:14 ljj

          我把插件工程 和主host 的代碼發(fā)到你郵箱了,幫看下吧,謝謝!  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-03-29 08:34 zh-weir

          不好意思,我可能周末才有時間看你的這份代碼哦……
          辦公室不讓收外部郵箱郵件,業(yè)余時間又少得可憐。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù)[未登錄] 2012-03-30 14:37 123

          @zh-weir
          按照這個方法我依然沒有實(shí)現(xiàn),我用的是PathClassLoader。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù)[未登錄] 2012-03-30 15:04 123

          @zh-weir
          你好,看了你的帖子的確讓我學(xué)到不少。

          但是我的實(shí)現(xiàn)依然存在問題。
          以下是我最近一個項(xiàng)目的需求:我要使我的App(容器端)中某個固定的View可以替換為其他開發(fā)者開發(fā)的任意自定義控件。目前利用PathClassLoader已經(jīng)實(shí)現(xiàn)了基本的替換功能。但是存在一個問題,跟上面幾位朋友討論的問題相似,在容器端我需要定義一些接口(目前是為了實(shí)現(xiàn)觀察者模式,當(dāng)然以后可能提供更多的接口用以添加容器端和插件端的交互),在插件端的自定義控件可以實(shí)現(xiàn)這些接口,但是根據(jù)樓上提供的方法,依然存在ClassCastException的問題。

          以下是我實(shí)現(xiàn)的一些細(xì)節(jié),請LZ看看哪里有問題:
          1.我使用的是PathClassLoader,因?yàn)椴寮枰话惭b,所以不用DexClassLoader。
          2.PathClassLoader構(gòu)造的時候使用的是getSystemClassLoader。
          3.利用Eclipse將接口導(dǎo)出到j(luò)ar(我這里不太清楚是否需要用dx工具將jar里面的.class類型轉(zhuǎn)化,我目前的做法是沒有轉(zhuǎn)化),且不含源文件,插件端可以編譯通過。  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2012-05-15 19:45 briancol

          博主:請教個問題:
          Dalvik 在加載類時, 如果該類已被加載,就不會重新加載。有么有辦法讓dalvik強(qiáng)制重新加載?
          這個需求的原因是因?yàn)椋?android系統(tǒng)有些自帶類會有各種限制,所以我想通過寫一個和系統(tǒng)某個類同包名同類名的類,然后讓dalvik加載我的這個類,從而突破某些限制。
          博主有沒有什么思路?  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2013-01-23 14:45 菜鳥1234

          不是很明白,既然有最后解密的過程,自然就可以找到解密的算法和密鑰,再怎么動態(tài)加載類又有什么用呢?  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2013-05-08 11:28 chuan

          說理清晰,thx  回復(fù)  更多評論   

          # re: Android類動態(tài)加載技術(shù) 2013-07-05 14:36 卷起鋪蓋流浪

          @briancol
          我和你在做同樣的事情,如果我想動態(tài)替換報名類名都相同的一個類,那么這個類dex加載后會被apk中存在的那個類的實(shí)例覆蓋,沒有實(shí)現(xiàn)動態(tài)加載的意義,請問你找到解決方法了么?  回復(fù)  更多評論   

          公告

          大家好!歡迎光臨我的 Android 技術(shù)博客!



          本博客旨在交流與 Android 操作系統(tǒng)相關(guān)的各種技術(shù)及信息。

          博客內(nèi)的文章會盡量以開源的形式提供給大家,希望我們能相互交流,共同提高!

          有不足之處,請不吝賜教!

          我的郵箱:zh.weir@gmail.com
          我的新浪微博:@囧虎張建偉

           

          導(dǎo)航

          <2011年10月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          統(tǒng)計

          留言簿(19)

          隨筆分類(24)

          隨筆檔案(18)

          文章檔案(1)

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 庄浪县| 佳木斯市| 额敏县| 盐亭县| 枣庄市| 马尔康县| 罗甸县| 报价| 曲水县| 柘荣县| 西丰县| 泽普县| 福建省| 双鸭山市| 陇西县| 新安县| 江都市| 澎湖县| 静安区| 兴文县| 高清| 盐城市| 岑溪市| 富民县| 山西省| 乌兰浩特市| 太和县| 奉新县| 中江县| 黔江区| 儋州市| 黄石市| 石首市| 永城市| 华安县| 常山县| 克拉玛依市| 保定市| 渭南市| 红安县| 常州市|