Android開發(fā)中類加載器DexClassLoader的簡(jiǎn)單使用講解
簡(jiǎn)介
“類裝載器”(ClassLoader),顧名思義,就是用來動(dòng)態(tài)裝載class文件的。標(biāo)準(zhǔn)的Java SDK中有個(gè)ClassLoader類,借助此類可以裝載需要的class文件,前提是ClassLoader類初始化必須制定class文件的路徑。
import關(guān)鍵字引用的類文件和ClassLoader動(dòng)態(tài)加載類的區(qū)別:
import引用類的兩個(gè)特點(diǎn):
1、必須存在于本地,當(dāng)程序運(yùn)行該類時(shí),內(nèi)部類裝載器會(huì)自動(dòng)裝載該類。
2、編譯時(shí)必須在現(xiàn)場(chǎng),否則編譯過程會(huì)因找不到引用文件而不能正常編譯。
classLoader的特點(diǎn)正好于import相反,而且更自由靈活。
每一個(gè)ClassLoader必須有一個(gè)父ClassLoader,在裝載Class文件時(shí),子ClassLoader會(huì)先請(qǐng)求其父ClassLoader加載該文件,只有當(dāng)其父ClassLoader找不到該文件時(shí),子ClassLoader才會(huì)繼承裝載該類。這是一種安全機(jī)制。對(duì)于Android而言,最終的apk文件包含的是dex類型的文件,dex文件是將class文件重新打包,打包的規(guī)則又不是簡(jiǎn)單地壓縮,而是完全對(duì)class文件內(nèi)部的各種函數(shù)表,變量表進(jìn)行優(yōu)化,產(chǎn)生一個(gè)新的文件,即dex文件。因此加載這種特殊的Class文件就需要特殊的類加載器DexClassLoader。
在Java中涉及到的類加載器就是ClassLoader這個(gè)類,通過ClassLoader.forName()的方法可以加載我們需要的類,從而實(shí)現(xiàn)在運(yùn)行時(shí)動(dòng)態(tài)加載類庫的需求。但是在android中直接使用ClassLoader是行不通的,因?yàn)镃lassLoader加載的java的字節(jié)碼文件,而在android中使用的是dex格式的字節(jié)碼,對(duì)此android專門提供了一個(gè)DexClassLoader類來完成動(dòng)態(tài)加載apk的需求。
實(shí)例
下面用一個(gè)簡(jiǎn)單的例子來說明一下DexClassLoader這個(gè)類的使用,這個(gè)例子涉及到兩個(gè)知識(shí)點(diǎn):跨包取資源 & 反射調(diào)用方法。 首先建立一個(gè)Client工程,這個(gè)工程很簡(jiǎn)單,只有一個(gè)簡(jiǎn)單的layout和一個(gè)sayHello()的方法。
public class Main extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.main); } @SuppressWarnings("unused") private void sayHello(String msg){ Log.d("mmtag",msg); } }
接著建立另外一個(gè)工程,在這個(gè)工程中調(diào)用client工程中的view和調(diào)用sayHello()方法。在這個(gè)類中主要涉及到了DexClassLoader這個(gè)類的使用。
package com.example.dexclassloaderserver; import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import dalvik.system.DexClassLoader; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.util.Log; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); useDexClassLoader(); } @SuppressLint("NewApi") public void useDexClassLoader() { Intent mIntent = new Intent(); mIntent.setClassName("com.example.dexclassloaderclient", "com.example.dexclassloaderclient.MainActivity"); PackageManager pm = this.getPackageManager(); List<ResolveInfo> mList = pm.queryIntentActivities(mIntent, PackageManager.MATCH_DEFAULT_ONLY); ResolveInfo info = mList.get(0); String apkPath = info.activityInfo.applicationInfo.sourceDir; String optPath = this.getCodeCacheDir().getAbsolutePath(); String libPath = info.activityInfo.applicationInfo.nativeLibraryDir; DexClassLoader clsLoader = new DexClassLoader(apkPath, optPath, libPath, this.getClass().getClassLoader()); try { Class cls = clsLoader .loadClass("com.example.dexclassloaderclient.MainActivity"); Object obj = cls.newInstance(); Method invokeMethod = cls.getDeclaredMethod("sayHello", new Class[] { String.class }); invokeMethod.setAccessible(true); invokeMethod.invoke(obj, "hello world,DexClassLoader"); } catch (Exception e) { e.printStackTrace(); } } }
生成的結(jié)果為:
I/dex2oat (20250): dex2oat took 1.547s (threads: 4) D/mmtag (20229): hello world,DexClassLoader D/OpenGLRenderer(20229): Render dirty regions requested: tru
這樣就成功的調(diào)用了其他的apk中的方法。
相關(guān)文章
Android Tween動(dòng)畫之RotateAnimation實(shí)現(xiàn)圖片不停旋轉(zhuǎn)效果實(shí)例介紹
Android中如何使用rotate實(shí)現(xiàn)圖片不停旋轉(zhuǎn)的效果,下面與大家共同分析下Tween動(dòng)畫的rotate實(shí)現(xiàn)旋轉(zhuǎn)效果,感興趣的朋友可以參考下哈2013-05-05Android DrawLayout結(jié)合ListView用法實(shí)例
這篇文章主要介紹了Android DrawLayout結(jié)合ListView用法實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09鴻蒙開源第三方組件之連續(xù)滾動(dòng)圖像組件功能
這篇文章主要介紹了鴻蒙開源第三方組件之連續(xù)滾動(dòng)圖像組件功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04Android Notification的多種用法總結(jié)
這篇文章主要介紹了Android Notification的多種用法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06android編程實(shí)現(xiàn)為程序創(chuàng)建快捷方式的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)為程序創(chuàng)建快捷方式的方法,實(shí)例分析了Android創(chuàng)建程序快捷方式的相關(guān)設(shè)置與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-11-11