关闭

记录android_async_load实现android插件开发步骤

标签: androidDynamicLoadApk插件教程
297人阅读 评论(0) 收藏 举报

主要介绍什么是android_async_load ,为什么要使用android_async_load进行开发,android_async_load开发的优,缺点;以及,使用android_async_load开发插件的步骤

android_async_load 即android 插件化开发。插件化开发可以分离apk中功能独立的部分,减少apk安装包的大小,针对特定节日首页引导页的动态切换。及时热修复bug,无序让用户手动下载安装文件等。android_async_load 优点 所有activity都需要继承自proxy avtivity(proxy avtivity负责管理所有activity的生命周期),无法启动apk内部的activity,不支持Service和BroadcastReceiver。

简单介绍android_async_load 之后,现在开始开发自己的第一个插件

1.在github上使用git命令clone android_async_load 或者直接下载该框架 地址为:https://github.com/singwhatiwanna/dynamic-load-apk。

2下载完成后在android studio 新建工程 ——>new——>import module


——>选中解压后lib目录


选中ok

2 创建宿主模块host和插件模块plugin,创建为安卓应用程序,以便于生成apk,如下图所示:


编译lib目录,命令是


在编译后的,找到lib\build\intermediates\bundles\debug\class.jar.修改class.jar 包为lib.jar。

3.把修改的lib.jar包复制到宿主host的libs文件夹下


编辑宿主host类

package com.atom.recyeleview.host;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.ryg.dynamicload.DLPlugin;
import com.ryg.dynamicload.internal.DLIntent;
import com.ryg.dynamicload.internal.DLPluginManager;
import com.ryg.utils.DLUtils;

import java.io.File;

public class HostActivity extends Activity {

    private TextView tvTip;
    private Button btn_test;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_host);
        this.tvTip = (TextView) findViewById(R.id.tvTip);
        this.btn_test = (Button) findViewById(R.id.btn_test);
        // 插件初始化操作
        this.init();
    }

    /**
     * 插件初始化
     */
    private void init() {

        // 获取插件路径
        String pluginFolder = "mnt/sdcard/DynamicLoadHost";
        // 创建文件对象
        File file = new File(pluginFolder);
        // 获取插件列表
        File[] plugins = file.listFiles();
        // 判断插件是否存在
        if (plugins == null || plugins.length == 0) {
            this.tvTip.setVisibility(View.VISIBLE);
            return;
        }
        // 调用第一个插件
        File plugin = plugins[0];
        // 创建插件bean对象
        final PluginItem item = new PluginItem();
        // 获取插件路径
        item.pluginPath = plugin.getAbsolutePath();
        // 获取插件包信息
        item.packageInfo = DLUtils.getPackageInfo(this, item.pluginPath);
        // 获取插件启动的Activity的名称
        if (item.packageInfo.activities != null && item.packageInfo.activities.length > 0) {
            item.launcherActivityName = item.packageInfo.activities[0].name;
        }
        // 获取插件启动的Serviece名称
        if (item.packageInfo.services != null && item.packageInfo.services.length > 0) {
            item.laucherActivityService = item.packageInfo.services[0].name;
        }
        // 显示插件
        tvTip.setText("检测到一个插件:" + item.pluginPath);
        // 加载插件
        DLPluginManager.getInstance(this).loadApk(item.pluginPath);
        // 添加监听
        this.btn_test.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 提示信息
                Toast.makeText(getApplication(), "开始调用插件", Toast.LENGTH_SHORT).show();
                // 调用插件
                usePlugin(item);
            }
        });
    }

    /**
     * 具体插件调用
     *
     * @param item
     */
    private void usePlugin(PluginItem item) {

        DLPluginManager pluginManager = DLPluginManager.getInstance(this);
        pluginManager.startPluginActivity(this, new DLIntent(item.packageInfo.packageName, item.launcherActivityName));
    }

    /**
     * 插件bean
     */
    public static class PluginItem {

        public PackageInfo packageInfo;
        public String pluginPath;
        public String launcherActivityName;
        public String laucherActivityService;

        public PluginItem() {

        }
    }
}

在宿主host 的mainfest.xml中引入注册文件

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<activity
            android:name="com.ryg.dynamicload.DLProxyActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="com.ryg.dynamicload.proxy.activity.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <activity
            android:name="com.ryg.dynamicload.DLProxyFragmentActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="com.ryg.dynamicload.proxy.fragmentactivity.VIEW"/>

                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

        <service android:name="com.ryg.dynamicload.DLProxyService"/>

4.把修改的lib.jar包复制到插件plugin的libs文件夹下


编辑插件plugin 类 主要这里插件plugin的activity 要继承DLBasePluginActivity类

package com.atom.recyeleview.plugin;

import android.os.Handler;
import android.os.Message;
import android.support.annotation.UiThread;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import com.ryg.dynamicload.DLBasePluginActivity;

public class PluginActivity extends DLBasePluginActivity {

    private Handler mHanlder = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case 0:
                    PluginActivity.this.finish();
                    break;
            }
        }
    };
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_plugin);
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(2000);
                    Message msg = new Message();
                    msg.what = 0;
                    mHanlder.sendMessage(msg);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

参考“梧桐那时雨”的博客:http://blog.csdn.net/fuchaosz/article/details/51056947



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:468次
    • 积分:24
    • 等级:
    • 排名:千里之外
    • 原创:2篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档