基于android的主题插件编写

简介:

前一段,写了一个主题插件,刚接到这个任务时,根本不知道从哪下手,于是就上网搜了一些资料,下面来讲一下我是怎么做这个主题插件的。

首先,我们需要引入一个插件包。这个架包是从网上下的,该作者的博客地址:http://hangxin1940.cnblogs.com/。这个架包封装了查找插件的功能,查找插件功能的功能等等,不需要我们自己在写,很方便。大家可以看看。

其次,我们要对自己的主程序的AndroidManifest.xml进行修改.

<manifestxmlns:android="http://schemas.android.com/apk/res/android"

package="你的app包名"

android:sharedUserId="你自己设的"

android:versionCode="1"

android:versionName="1.0">

这里的package和sharedUserId都是必须写的。写package方便我们在主程序中获取插件的Context对象,去引用插件的内部资源。而sharedUserId的值必须和主程序一致,可以保证我们的插件和主程序共享一个进程,消除权限堡垒,方便我们共享两个程序之间的资源


接下来,我们需要在主程序中写查找插件的代码

// 首先,就是查找插件

       PluginSearchpsearch = newPluginSearch();

       List<Plugin>plugins = psearch.getPlugins(context);


// 然后将插件再组装一下

       PluginBuilderpbuilder = newPluginBuilder(context);

       plugins= pbuilder.buildPluginsDescrition(plugins);


// 显示出所有插件

       flateUI(plugins);


then,我们要显示插件皮肤,并调用插件中写的方法(即实现的功能)


for (final Pluginplug : plugins) {

// 加入插件

           ThemePluginItemitem = newThemePluginItem(this);


// 获取插件的描述对象

PluginDescription<MainDescript> pdes = newPluginDescription<MainDescript>(

                   MainDescript.class);

           MainDescriptdes;

try {

               des= pdes.getDescription(this, plug);

// 设置插件item的描述信息

               Drawabled = plug.getContext().getResources()

                       .getDrawable(des.getIconResId());

               item.setDrawableTheme(d);


           }catch(java.lang.InstantiationException e1) {

// TODOAuto-generated catch block

               e1.printStackTrace();

           }


// 获得当前插件的功能

           List<PluginFeature>features = plug.getFeatures();


// 遍历功能

for (finalPluginFeature pf : features) {


for (finalPluginFeatureMethod fm : pf.getMethods()) {


// 添加插件,并且设置执行事件

                   item.addPluginMethod(fm,new OnClickListener(){


@Override

publicvoidonClick(View v) {

                                       PluginInvokepi = newPluginInvoke(getApplicationContext());


try {

try {

                                   pi.invoke(plug,pf, fm);

                           }catch (java.lang.InstantiationExceptione) {


                                   e.printStackTrace();

                               }

//注意这个地方:我本想用反射在插件中调用主程序的方法,但是一直出错。

//并不是主程序的所有资源我们都可以调用的,比如说控件,我们是不可能使用其他应用程序的//插件的,所以一些功能还是要在主程序中写的

if(mIsUpdate){

                                   setBabySkinIsupdate();

                               }else {

                                   setBabySkin();

                               }

alertDialog.dismiss();


                           }catch(SecurityException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(IllegalArgumentException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(NameNotFoundException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(ClassNotFoundException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(IllegalAccessException e) {

// TODOAuto-generated catch block

                            } catch(InstantiationException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(NoSuchMethodException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }catch(InvocationTargetException e) {

// TODOAuto-generated catch block

                               e.printStackTrace();

                           }

                       }

                   });

               }

           }

// 将插件加入到ui

addThemeLayout.addView(item);


       }

主程序中还需要再写一个类,来调用执行插件的功能,这是ThemePluginItem类中执行插件方法的代码

publicvoidaddPluginMethod(PluginFeatureMethod method,OnClickListener ocl){

//这是调用插件方法的接口形式,可以是Button控件在主程序中显示,也可以是ImageView等其他控件。

       ImageViewthemeImageView  = newImageView(mContext);

       LinearLayout.LayoutParamslayoutParams = newLinearLayout.LayoutParams(75, 75);

       layoutParams.setMargins(7,5, 5, 5);

       themeImageView.setLayoutParams(layoutParams);

//themeImageView.setImageResource(R.drawable.baby_info_pink);

       themeImageView.setImageDrawable(getDrawableTheme());

       themeImageView.setAdjustViewBounds(false);

         themeImageView.setClickable(true);          

       themeImageView.setScaleType(ScaleType.CENTER);      

       //这是触发插件的功能

themeImageView.setOnClickListener(ocl);

//我们要把插件放到主程序中显示

otherThemeLayout.addView(themeImageView);


   }

以上是主程序中查找插件并调用插件的过程,下面讲一下插件中的功能是怎么共享主程序的文件。

我们知道在写主题功能时,为了分清我们触发的是哪个皮肤,我们需要为每个皮肤进行编号,并把这些内容用Sharepreference方法存储到一个文件中,方便我们调用和使用,但是在插件中如何去共享并操作这份文件呢,android已经为我们提供这样一些参数


MODE_PRIVATE 0 代表了该文件只为本程序所访问

MODE_WORLD_READABLE 1 代表了该文件可以被其他程序读取

MODE_WORLD_WRITEABLE 2 代表了该文件可以被其他程序写


//首先,我们需要得到主程序的context对象

Contextc= context.createPackageContext(你要调用的项目的包名, Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);

       //这里面有两个参数,第一个是你的文件名,第二个:设置你的文件权限

           SharedPreferencesmSharedPreferences = c.getSharedPreferences(你要调用的项目的包名, context.MODE_WORLD_READABLE|context.MODE_WORLD_WRITEABLE);

           EditormEditor = mSharedPreferences.edit();

//获取该文件的isupdate对应的值

boolean mIsUpdate= mSharedPreferences.getBoolean("isupdate"false);

//在文件中写入自己想存入的值

   mEditor.putInt(mBabyID+ "", mNewBabySkin);



这样我们就达到了共享文件的功能。

前面已经说明我们无法共享控件,所以设置主程序的皮肤还是要是要在主程序中设置。

在这个环节,最重要的就是获取插件的资源

//获取插件的Context对象

Context c=context.createPackageContext(你要调用的项目的包名,

                                 Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY);

//获取插件的资源resources对象,这样我们就可以获取插件中的资源

   ResourcespluginResources = c.getResources();

//获取插件中的图片,这里千万不要以为只用获取插件图片的ID,就可以让主程序来引用,我们要知道每个应用程序都有一个R文件,这里面的数都是自动生成且唯一的,而且只包含本程序的资源,所以我们要用这种方法获得插件中的图片资源


babyYellowBg =pluginResources.getDrawable(pluginResources.getIdentifier("你的图片名称""drawable",

你要调用的项目的包名));

在这里我们的主程序就可以直接引用了

        scrollView.setBackgroundDrawable(babyYellowBg);


最后, 我需要告诉你大家,我们在主程序中引用插件中的资源或者插件引用主程序中的资源时,不能引用style.xml中的值,因为他属于多属性值,android还没有提供相应的方法来直接引用,如果哪位读者找到了读取插件style文件的方法,还望不吝赐教



本文转自HDDevTeam 51CTO博客,原文链接:http://blog.51cto.com/hddev/1217507,如需转载请自行联系原作者


相关文章
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
711 1
|
缓存 程序员 定位技术
Android Studio 插件,那些被大厂优化的程序员们
Android Studio 插件,那些被大厂优化的程序员们
|
Android开发 开发者
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
Android UI设计: 请解释Activity的Theme是什么,如何更改应用程序的主题?
494 1
|
人工智能 移动开发 Java
Android Studio插件版本与Gradle 版本对应关系
Android Studio插件版本与Gradle 版本对应关系
4001 0
Android Studio插件版本与Gradle 版本对应关系
|
Java 开发工具 Android开发
Cocos Creator 2.4.6 Android Gradle 版本升级为 6.5.1(插件4.1.0)
Cocos Creator 2.4.6 Android Gradle 版本升级为 6.5.1(插件4.1.0)
527 1
|
5月前
|
监控 Android开发 数据安全/隐私保护
批量发送短信的平台,安卓群发短信工具插件脚本,批量群发短信软件【autojs版】
这个Auto.js脚本实现了完整的批量短信发送功能,包含联系人管理、短信内容编辑、发送状态监控等功能
|
9月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
2073 77
|
5月前
|
API Android开发
微信虚拟摄像头模块,微信虚拟视频聊天,安卓虚拟摄像头插件
该实现包含虚拟摄像头服务核心、视频流生成和Android配置三个关键模块,使用Camera2
|
6月前
|
存储 JSON API
安卓ck提取工具,可提取手机cookie插件,AUTOJS即可实现
怎么用autojs提取手机端的CK?其实autojs是支持提取ck的但是他提取的不是浏览器的CK,二十他自身浏览器环境的c