热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

资源的插件化

--摘自《android插件化开发指南》1.android资源文件分为两类:第一类是res目录下存放的可编译资源文件,编译时,系统会自动在

--摘自《android插件化开发指南》

1.android资源文件分为两类:

第一类是res目录下存放的可编译资源文件,编译时,系统会自动在R.java中生成资源文件的十六进制值

Resources resources = getResources();
String appName
= resources.getString(R.string.app_name);               

第二类是assets目录下存放的原始资源文件,apk在编译时不会编译assets下的资源文件

Resources resources = getResources();
AssetManager am
= getResources().getAssets();
InputStream is
= getResources().getAssets().open("filename");

2.Resources内部各种方法其实都是间接调用AssetManager的内部方法。AssetManager的addAssetPath方法会在app启动的时候把当前apk的路径传进去,就能访问apk的所有资源了。在这里可以把插件apk的资源塞进去

3.apk打包时会生成一个resource.arsc文件,它就是一个Hash表,存放着每个十六进制值和资源的对应关系

***资源的插件化解决方案***

public class Dynamic implements IDynamic {@Overridepublic String getStringForResId(Context context) {return context.getResources().getString(R.string.myplugin1_hello_world);}
}

Plugin1myplugin1_hello_world

public class BaseActivity extends Activity {private AssetManager mAssetManager;private Resources mResources;private Resources.Theme mTheme;private String dexpath = null; //apk文件地址private File fileRelease = null; //释放目录protected DexClassLoader classLoader = null;private String pluginName = "plugin1.apk";TextView tv;@Overrideprotected void attachBaseContext(Context newBase) {super.attachBaseContext(newBase);Utils.extractAssets(newBase, pluginName);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//第三步:加载外部的插件,生成插件对应的ClassLoaderFile extractFile = this.getFileStreamPath(pluginName);dexpath = extractFile.getPath();fileRelease = getDir("dex", 0);classLoader = new DexClassLoader(dexpath, fileRelease.getAbsolutePath(), null, getClassLoader());}/*** 第一步:通过反射,创建AssetManager对象,调用addAssetPath方法,把插件Plugin的路径添加到这个AssetManager对象中**/protected void loadResources() {try {AssetManager assetManager = AssetManager.class.newInstance();Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);addAssetPath.invoke(assetManager, dexpath);mAssetManager = assetManager;} catch (Exception e) {e.printStackTrace();}Resources superRes = super.getResources();superRes.getDisplayMetrics();superRes.getConfiguration();mResources = new Resources(mAssetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());mTheme = mResources.newTheme();mTheme.setTo(super.getTheme());}/*** 第二步:重写Acitivity的getAsset,getResources和getTheme方法**/@Overridepublic AssetManager getAssets() {return mAssetManager == null ? super.getAssets() : mAssetManager;}@Overridepublic Resources getResources() {return mResources == null ? super.getResources() : mResources;}@Overridepublic Resources.Theme getTheme() {return mTheme == null ? super.getTheme() : mTheme;}
}

public class MainActivity extends BaseActivity {TextView tv;@SuppressLint("NewApi")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button btn_6 = (Button) findViewById(R.id.btn_6);tv = (TextView)findViewById(R.id.tv);//带资源文件的调用btn_6.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View arg0) {loadResources();Class mLoadClassDynamic = null;try {//第四步:通过反射,获取插件中的类,构造出插件类的对象dynamicObject,然后就可以让插件中的类读取插件中的资源了mLoadClassDynamic = classLoader.loadClass("jianqiang.com.plugin1.Dynamic");Object dynamicObject = mLoadClassDynamic.newInstance();IDynamic dynamic = (IDynamic) dynamicObject;String content = dynamic.getStringForResId(MainActivity.this);tv.setText(content);Toast.makeText(getApplicationContext(), content + "", Toast.LENGTH_LONG).show();} catch (Exception e) {Log.e("DEMO", "msg:" + e.getMessage());}}});}
}

还有换肤

欢迎关注我的微信公众号:安卓圈

转:https://www.cnblogs.com/anni-qianqian/p/10103110.html



推荐阅读
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
  • 本文介绍了Android中的assets目录和raw目录的共同点和区别,包括获取资源的方法、目录结构的限制以及列出资源的能力。同时,还解释了raw目录中资源文件生成的ID,并说明了这些目录的使用方法。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
author-avatar
zmhua123_681
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有