设为首页 加入收藏

TOP

自己动手写Android插件化框架,让老板对你刮目相看(七)
2019-09-01 23:14:27 】 浏览:138
Tags:自己 手写 Android 插件 框架 老板 刮目相看
urn false; } mPluginApp = loadPluginApk(apkPath); return mPluginApp != null; } public PluginApp getLoadedPluginApk() { return mPluginApp; } }

在MainActivity中初始化,注意Hook的时机:

public class MainActivity extends Activity implements View.OnClickListener {
    // https://zhuanlan.zhihu.com/p/33017826

    public static final boolean DEBUG = true;
    public static final String TAG = "MainActivity";

    private String mPluginPackageName = "top.vimerzhao.image";
    private String mPluginClassName = "top.vimerzhao.image.MainActivity";

    //读写权限
    private static String[] PERMISSIONS_STORAGE = {Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};
    //请求状态码
    private static int REQUEST_PERMISSION_CODE = 1;

    private PluginManager mPluginManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initData();
        initView();
        initPlugin();
    }


    private void initPlugin() {
        // !! must first
        ReflectUtil.init();

        mPluginManager = PluginManager.getInstance(getApplicationContext());
        mPluginManager.hookInstrumentation();
        mPluginManager.hookCurrentActivityInstrumentation(this);
    }

    private void initData() {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
            }
        }
    }

    private void initView() {
        (findViewById(R.id.tv_launch)).setOnClickListener(this);
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
        // !!! 不要在此Hook,看源码发现mInstrumentaion会在此方法后初始化
    }

    @Override
    public void onClick(View view) {
        if (Constants.DEBUG) Log.e(TAG, "click view id: " + view.getId());
        if (view.getId() == R.id.tv_launch) {
            // TODO launch plugin app
            if (mPluginManager.loadPlugin(Constants.PLUGIN_PATH)) {
                Intent intent = new Intent();
                intent.setClassName(mPluginPackageName, mPluginClassName);
                startActivity(intent);
            }
        }

    }
}

现在插件Activity不会有任何限制:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    protected void onResume() {
        super.onResume();

    }
}

效果和上图类似。

Demo地址

部分源码无关核心逻辑,没有给到,目录结构也没有说明,详见Demo源码。

PluginDemo

总结

看着理论感觉似懂非懂,实战发现问题其实挺多的,尤其是Hook的时机,照搬网上的文章发现根本不可行。插件化也不是一蹴而就的,而是在已有成果的基础上一次一次的小创新积累起来的,跟着插件化发展的路径自己动手实践一遍还是能发现很多自己理解不够深刻的地方的。

以上。

参考

相关阅读
获得InputStream,读取配置文件的方式
聊聊springboot session timeout参数设置
Android开发之漫漫长途 XII——Fragment详解
【每日课程推荐】机器学习实战!快速入门在线广告业务及CTR相应知识

此文已由作者授权腾讯云+社区发布,更多原文请点击

搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!

海量技术实践经验,尽在云加社区

首页 上一页 4 5 6 7 下一页 尾页 7/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android6.0 源码修改之屏蔽系统短.. 下一篇VR一体机如何退出FFBM(QFIL)

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目