`
iaiai
  • 浏览: 2180533 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Android动态加载jar、apk的实现

 
阅读更多
      核心类
      1.1      DexClassLoader类
   可以加载jar/apk/dex,可以从SD卡中加载未安装的apk。
   1.2      PathClassLoader类  
   只能加载已经安装到Android系统中的apk文件。

    一、正文
       1.1 动态加载jar
    类似于eclipse的插件化实现, 首先定义好接口, 用户实现接口功能后即可通过动态加载的方式载入jar文件, 以实现具体功能。注意, 这里的jar包需要经过android dx工具的处理 , 否则不能使用。
首先我们定义如下接口 :

package com.example.interf;    
/**  
 * @Title: ILoader.java  
 * @Package com.example.loadjardemo  
 * @Description:  通用接口, 需要用户实现 
 * @version V1.0  
 */  
public interface ILoader {  
     public String sayHi();  
}

用户需实现,该接口, 并且将工程导出为jar包的形式。
示例如下 :
public class JarLoader implements ILoader {  
  
    public JarLoader() {  
    }  
  
    @Override  
    public String sayHi() {  
        return "I am jar loader.";  
    }  
  
}

最后, 实现功能的代码打包成jar包 :
首先选中工程, 右键后选择“导出”, 然后选择“java”-----“jar文件”, 然后将你的具体功能实现类导出为jar,文件名为loader.jar,如下图所示 :

将打包好的jar拷贝到SDK安装目录android-sdk-windows\platform-tools下,DOS进入这个目录,执行如下命令:
dx --dex --output=loader_dex.jar loader.jar

然后将loader_dex.jar放到android手机中, 这里我们放到SD卡根目录下。

动态加载代码 :
/** 
 *  
 * @Title: loadJar  
 * @Description: 项目工程中必须定义接口, 而被引入的第三方jar包实现这些接口,然后进行动态加载 。 
 *          相当于第三方按照接口协议来开发, 使得第三方应用可以以插件的形式动态加载到应用平台中。 
 * @return void     
 * @throws 
 */  
private void loadJar(){  
       final File optimizedDexOutputPath = new File(Environment.getExternalStorageDirectory().toString()  
               + File.separator + "loader_dex.jar");  
             
           BaseDexClassLoader cl = new BaseDexClassLoader(Environment.getExternalStorageDirectory().toString(),  
                optimizedDexOutputPath, optimizedDexOutputPath.getAbsolutePath(), getClassLoader());  
           Class libProviderClazz = null;  
             
           try {  
               // 载入JarLoader类, 并且通过反射构建JarLoader对象, 然后调用sayHi方法  
               libProviderClazz = cl.loadClass("com.example.interf.JarLoader");  
               ILoader loader = (ILoader)libProviderClazz.newInstance();  
               Toast.makeText(MainActivity.this, loader.sayHi() , Toast.LENGTH_SHORT).show();  
           } catch (Exception exception) {  
               // Handle exception gracefully here.  
               exception.printStackTrace();  
           }  
}

效果如下图所示 :

1.2 加载未安装的apk
     首先新建一个Android项目, 定义如下接口 :
public interface ISayHello {  
    public String sayHello()  ;  
}

定义一个Activity实现该接口, 如下:
package com.example.loaduninstallapkdemo;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.view.Menu;  
import android.view.View;  
import android.view.View.OnClickListener;  
import android.widget.Toast;  
  
/** 
 *  
 * @ClassName: UninstallApkActivity  
 * @Description: 这是被动态加载的Activity类 
 * 
 */  
public class UninstallApkActivity extends Activity implements ISayHello{  
  
    private View mShowView = null ;  
      
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
          
        mShowView = findViewById(R.id.show) ;  
        mShowView.setOnClickListener(new OnClickListener() {  
              
            @Override  
            public void onClick(View v) {  
                Toast.makeText(UninstallApkActivity.this, "这是已安装的apk被动态加载了", Toast.LENGTH_SHORT).show();  
            }  
        }) ;  
    }  
  
    @Override  
    public boolean onCreateOptionsMenu(Menu menu) {  
        // Inflate the menu; this adds items to the action bar if it is present.  
        getMenuInflater().inflate(R.menu.activity_main, menu);  
        return true;  
    }  
  
    @Override  
    public String sayHello(){  
        return "Hello, this apk is not installed";  
    }  
}

然后将该编译生apk, 并且将该apk拷贝到SD卡根目录下。
动态加载未安装的apk
/** 
 *  
 * @Title: loadUninstallApk  
 * @Description: 动态加载未安装的apk 
 * @return void     
 * @throws 
 */  
private void loadUninstallApk(){  
       String path = Environment.getExternalStorageDirectory() + File.separator;  
       String filename = "LoadUninstallApkDemo.apk";  
  
       // 4.1以后不能够将optimizedDirectory设置到sd卡目录, 否则抛出异常.  
       File optimizedDirectoryFile = getDir("dex", 0) ;  
       DexClassLoader classLoader = new DexClassLoader(path + filename, optimizedDirectoryFile.getAbsolutePath(),  
                                                        null, getClassLoader());  
  
       try {  
        // 通过反射机制调用, 包名为com.example.loaduninstallapkdemo, 类名为UninstallApkActivity  
           Class mLoadClass = classLoader.loadClass("com.example.loadunstallapkdemo.UninstallApkActivity");  
           Constructor constructor = mLoadClass.getConstructor(new Class[] {});  
           Object testActivity = constructor.newInstance(new Object[] {});  
             
           // 获取sayHello方法  
           Method helloMethod = mLoadClass.getMethod("sayHello", null);  
           helloMethod.setAccessible(true);  
           Object content = helloMethod.invoke(testActivity, null);  
           Toast.makeText(MainActivity.this, content.toString(), Toast.LENGTH_LONG).show();  
             
       } catch (Exception e) {  
           e.printStackTrace();  
       }  
}

DexClassLoader 注意点 :
A class loader that loads classes from .jar and .apk files containing a classes.dex entry. This can be used to execute code not installed as part of an application.

This class loader requires an application-private, writable directory to cache optimized classes. Use Context.getDir(String, int) to create such a directory:
File dexOutputDir = context.getDir("dex", 0);

Do not cache optimized classes on external storage. External storage does not provide access controls necessary to protect your application from code injection attacks.


效果如图 :

1.3 加载已安装的apk
将1.2中的apk安装到手机中,我的例子中,该apk的包名为“com.example.loaduninstallapkdemo”,Activity名为"UninstallApkActivity". 加载代码如下 :
/** 
*  
* @Title: loadInstalledApk  
* @Description: 动态加载已安装的apk     
* @return void     
* @throws 
*/  
rivate void loadInstalledApk() {  
try {  
    String pkgName = "com.example.loaduninstallapkdemo";  
    Context context = createPackageContext(pkgName,  
            Context.CONTEXT_IGNORE_SECURITY | Context.CONTEXT_INCLUDE_CODE) ;  
      
    // 获取动态加载得到的资源  
    Resources resources = context.getResources() ;  
    // 过去该apk中的字符串资源"tips", 并且toast出来,apk换肤的实现就是这种原理  
    String toast = resources.getString(resources.getIdentifier("tips", "string", pkgName) ) ;  
    Toast.makeText(MainActivity.this, toast, Toast.LENGTH_SHORT).show() ;  
      
    Class cls = context.getClassLoader().loadClass(pkgName + ".UninstallApkActivity") ;  
    // 跳转到该Activity  
    startActivity(new Intent(context, cls)) ;  
} catch (NameNotFoundException e) {  
    e.printStackTrace();  
}catch (ClassNotFoundException e) {  
    Log.d("", e.toString()) ;  
}

效果如图:

息被Toast出来, 并且跳转到了目标Activity.
  • 大小: 80.3 KB
  • 大小: 77.8 KB
  • 大小: 83 KB
  • 大小: 87.6 KB
分享到:
评论

相关推荐

    android动态加载jar

    在Android开发中,动态加载JAR(Java Archive)文件是一种常见的技术,它允许应用程序在运行时加载和执行不在原始APK文件中的代码。这种技术有多种应用场景,例如更新功能、热修复、插件化框架等。下面将详细介绍...

    Android动态加载未安装apk, jar

    1. 插件化开发:Android插件化是实现动态加载的基础,通过将应用的部分功能模块化,形成独立的apk或jar包,这些模块可以在运行时动态加载到主应用中。这样可以降低应用的体积,便于分发和更新。 2. ClassLoader重写...

    动态加载Apk、Jar

    本文将深入探讨如何通过自定义ClassLoader实现动态加载Apk和Jar包的功能。 首先,我们要理解ClassLoader的基本概念。在Java中,ClassLoader是负责加载类到JVM(Java虚拟机)的核心组件。它按照类名查找并加载相应的...

    android动态加载jar文件中的图片

    动态加载jar文件中的图片在Android中并非直接支持的功能,但通过自定义实现,我们可以绕过限制。关键在于正确地读取和解析jar文件,以及将图片数据转换为Android的`Bitmap`对象。这个过程涉及到了文件流操作、Zip...

    Android动态加载jar/dex,基于android studio+android开发艺术其他demo

    在Android应用开发中,动态加载jar或dex文件是一种常见的优化技术,它允许应用程序在运行时加载新的代码或库,而不必通过更新整个apk来实现功能的扩展或修复。这种技术通常用于热修复、插件化或者模块化开发,能够极...

    Android 中动态加载.jar的实现步骤

    在Android平台上,动态加载.jar文件是一项关键的技术,它允许应用程序在运行时加载新的功能或更新代码,无需重新安装整个应用。下面将详细讲解这一过程的实现步骤和涉及到的知识点。 首先,我们需要创建.jar文件。...

    Qt on Android调用Jar包

    【Qt on Android调用Jar包】是一个重要的技术实践,它涉及到跨平台开发和Java与C++的交互。在Android平台上,Qt提供了一种强大的方式来创建原生应用程序,但有时我们可能需要集成已经存在的Java库(以.jar文件形式)...

    android工程正确导入jar包

    在Android Studio中,我们有两种主要的方式:通过Gradle依赖管理和手动添加jar包。 3. **通过Gradle管理依赖**: - 在`build.gradle` (Module: app) 文件中添加依赖项: ```groovy dependencies { ...

    Android10静默安装APK

    在Android系统中,静默安装APK(Silent Install)是指在用户无感知的情况下自动安装应用程序。这通常需要系统的特殊权限,因为出于安全考虑,Android系统默认不允许非系统应用进行后台安装。在Android 10中,由于...

    Android 通过反射启动未安装的APK中的Activity

    2. **解析APK**:然后,使用ZipFile或JarFile类解析APK,提取AndroidManifest.xml文件的内容。XMLPullParser可以帮助我们解析XML,找到Activity的相关信息,如类名和Intent过滤器。 3. **加载类**:有了Activity的...

    Android中的动态加载机制(折腾版) 源码

    DexClassLoader可以加载APK、.jar或包含.dex的.zip文件,非常适合于动态加载。 3. DexOpt:在Android中,当.dex文件被加载时,系统会进行dex优化,将其转换为OAT(Optimized Android bytecode)文件,以提高执行...

    动态加载apk或者jar或者dex.docx

    ### 动态加载APK或JAR或DEX详解 #### 前言 在移动应用开发领域,用户体验一直是开发者关注的核心。随着技术的发展,Native App 和 Web App 在用户体验上各有千秋,但频繁的版本更新成为了 Native App 面临的一大...

    apk文件中添加jar文件

    本篇文章将详细讲解如何在APK文件中添加JAR文件,以及涉及到的相关工具——baksmali、apktool和jar2dex。 首先,我们来理解一下JAR文件。Java Archive(JAR)文件是Java平台中用于存储类文件、资源文件和其他相关...

    Android Studio打包生成APK教程.rar

    - 使用AAR库而不是JAR库,因为AAR支持按需加载。 - 依赖项管理:检查并移除不必要的第三方库。 - 使用动态分发:对于大体积的资源,可以考虑通过Google Play服务动态分发。 - 采用Android App Bundle,它会根据...

    Android插件jar

    - **动态加载**:Android系统并不直接支持运行时动态加载第三方库,但通过反射和 DexClassLoader 等技术,可以在运行时加载新的jar或apk文件,实现插件化。 2. **创建与使用Android插件jar**: - **创建jar**:...

    Android代码-安卓apk加壳工程

    在Android开发中,“安卓apk加壳工程”是一个常见的术语,指的是通过在原始APK(Android应用程序包)外部添加一层或多层包装,以实现特定功能或保护应用原代码的技术。这通常涉及到动态加载、代码混淆、反编译防御等...

    android apk sha256哈希值签名验证示例

    在Java层,可以使用`java.security.cert.CertificateFactory`和`java.util.jar.JarFile`类来实现。以下是一个简单的Java示例: ```java import java.io.File; import java.security.cert.CertificateException; ...

    android正确导入jar包

    当使用Eclipse作为开发工具时,按照常规方法添加jar包(通过`Build Path -> Java Build Path -> Libraries -> Add External JARS`),可能会遇到以下错误: 1. **转换为Dalvik格式失败**:控制台报错“conversion ...

    最新版本android exoplayer jar

    综上所述,最新版本的Exoplayer jar库为Android开发者提供了一套全面的多媒体播放解决方案,涵盖多种流媒体协议、用户界面元素以及音频解码,极大地简化了媒体播放功能的实现,同时保持了高度的定制性和性能表现。...

    android v7Google最新源码 jar包

    通过研究这个"android v7Google最新源码 jar包",开发者可以了解这些组件的实现细节,进行自定义扩展,解决特定问题,或者优化性能。源代码的学习对于提升开发技能,理解和掌握Android系统的底层机制非常有帮助。...

Global site tag (gtag.js) - Google Analytics