android应用Theme(二)
另外一种实现android应用Theme的方式是通过apk来实现的。
以下是一个demo。
1.首先必须新建一个apk。类似的插件,然后在该apk的AndroidManifest.xml文件的application加上一个meta-data。这个是下一步查找是否是自己的插件的apk做一个标记。
<meta-data android:name="skin_demo2_plugin" android:value="com.example.skindemo2.icon"/>
2.在该apk加入一些图片,也能够用其它(包含style等)这里主要是为了演示。在该apk的MainActivity定义一个方法。
这里主要为了方便主apk高速调用这种方法。
static int allDrawableId[] = {R.drawable.img_apparel_accessories,R.drawable.img_computers_software
,R.drawable.img_electro,R.drawable.img_electronics,R.drawable.img_entertaiment
,R.drawable.img_food_beverage,R.drawable.img_kids_baby,R.drawable.img_sport,R.drawable.img_toys_games}; public int getDrawableIdForOtherApp(int position){ if(position < allDrawableId.length){
return allDrawableId[position];
}
return 0;
}
3.在主apk中通过读取全部安装的应用,通过分析applicationInfo的meta-data。然后推断是否是自己的插件apk。
然后通过context.createPackageContext(packageName,int flag)得到对应插件的context。然后通过类载入器得到MainActivity的class类。然后通过反射得到方法返回的值。然后就能够得到drawable对象。
package com.example.skindemo2;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView; public class MainActivity extends Activity { private Button mSwtichImgBgBtn;
private ImageView mShowImg;
private Context context;
private ArrayList<String> mPluginPackageNameList = new ArrayList<String>();
private int position = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
mSwtichImgBgBtn = (Button) this.findViewById(R.id.swtichImgBgBtn);
mSwtichImgBgBtn.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
swtichImgUsePlugin();
}
});
mShowImg = (ImageView) this.findViewById(R.id.myShowImg);
new AsyncTask<Void, Void, Void>() { @Override
protected Void doInBackground(Void... params) {
findPluginPackageName();
return null;
} @Override
protected void onPostExecute(Void result) {
swtichImgUsePlugin();
super.onPostExecute(result);
}
}.execute(); } private void findPluginPackageName() {
PackageManager pm = context.getPackageManager();
List<PackageInfo> list = pm.getInstalledPackages(0);//得到全部安装的apk的PackageInfo
String meta = null;
ApplicationInfo aInfo = null;
for (PackageInfo pi : list) {
String pkgName = pi.packageName;
try {
aInfo = pm.getApplicationInfo(pkgName,
PackageManager.GET_META_DATA);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
if (aInfo == null || aInfo.metaData == null)
continue;
meta = aInfo.metaData.getString("skin_demo2_plugin");
if (meta == null || "".equals(meta))
continue;
if ("com.example.skindemo2.icon".equals(meta)) {
//通过meta的值推断是否是自己的插件apk
mPluginPackageNameList.add(aInfo.packageName);
}
}
}
//必须在主线程中操作
private void swtichImgUsePlugin() {
//我这里为了方便直接就取了第一个插件apk数据。实际中是通过用户选择的apk来切换
if (mPluginPackageNameList.size() != 0) {
try {
//通过createPackageContext方法得到插件apk的context
Context otherplusContext = context.createPackageContext(
mPluginPackageNameList.get(0),
Context.CONTEXT_INCLUDE_CODE
| Context.CONTEXT_IGNORE_SECURITY);
//通过得到插件apk的context类载入器,然后得到MainActvity的类对象
Class<?> mainClass = otherplusContext
.getClassLoader()
.loadClass(mPluginPackageNameList.get(0) + ".MainActivity");
//通过反射得到对应位置的drawable
Method m = mainClass.getMethod("getDrawableIdForOtherApp",
int.class);
int imgBgId = (Integer) m.invoke(mainClass.newInstance(), position);
//为了能够循环切换img
if(imgBgId == 0){
position = 0;
}else{
position += 1;
}
//得到drawable对象
Drawable drawable = otherplusContext.getResources()
.getDrawable(imgBgId);
mShowImg.setImageDrawable(drawable);
} catch (Exception e) {
e.printStackTrace();
}
} }
}
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmd5YW5iaW4xMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
android应用Theme(二)的更多相关文章
- Android进阶笔记06:Android 实现扫描二维码实现网页登录
一. 扫描二维码登录的实现机制: 详细流程图: (1)PC端打开网页(显示出二维码),这时候会保存对应的randnumber(比如:12345678). (2)Android客户端扫码登录,Andro ...
- Android中theme.xml与style.xml的区别
一.相同点 两者的定义相同.继承方式也相同 <?xml version="1.0" encoding="utf-8"?> <resources ...
- Android 短信模块分析(二) MMS中四大组件核心功能详解
接下来的分析先从MMS中四大组件(Activity ,BroadCastReceiver,Service,ContentProvider),也是MMS中最核心的部分入手: 一. Activity 1 ...
- Android快速实现二维码扫描--Zxing
Android中二维码扫描的最常用库是zxing和zbar,zxing项目地址为https://github.com/zxing/zxing,目前还有多个人在维护.zbar主要用C来写的,对速度有要求 ...
- android 中theme.xml与style.xml的区别
from://http://liangoogle.iteye.com/blog/1848448 android 中theme.xml与style.xml的区别: 相同点: 两者的定义相同. <r ...
- Android 切换主题 (二)
Android 切换主题 (二) 背景 我原来写过一篇文章关于 android 切换主题的文章 -- Android 切换主题以及换肤的实现 , 里面介绍了如何使用 setTheme() 来切换主题, ...
- 社会化登录分享-Android SDK的二次封装和使用
本系列文章将第三方的登录分享功能进行二次封装,统一接口调用,简化了接不同平台登录分享的步骤. 0 系列文章 系列一 Android SDK的二次封装和使用 系列二 源码解析 系列三 微信SDK接入 系 ...
- Android仿微信二维码扫描
转载:http://blog.csdn.net/xiaanming/article/details/10163203 了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从一 ...
- Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
嵌套Fragment的使用及常见错误 嵌套Fragments (Nested Fragments), 是在Fragment内部又添加Fragment. 使用时, 主要要依靠宿主Fragment的 ge ...
随机推荐
- Linux中如何查看文件夹的大小
直接查看当前文件夹的大小: du –sh 只看文件夹的名字里包含某字符串的子文件夹的大小: du –h –d 1 | grep "BACKEND" 我的linux系统被阉割的比较厉 ...
- 前端性能优化:配置ETag
什么是ETag? 实体标签(EntityTag)是唯一标识了一个组件的一个特定版本的字符串,是web服务器用于确认缓存组件的有效性的一种机制,通常可以使用组件的某些属性来构造它. 条件GET请求 浏览 ...
- python3 杀死进程
在windows10杀死进程:Shadowsocks.exe os.system('taskkill /f /im %s' % 'Shadowsocks.exe')
- java log4j日志配置
1.首先看pom.xml文件,需要以下配置 <dependency> <groupId>log4j</groupId> <artifactId>log4 ...
- [转]PostgreSQL Replication之扩展与BDR
原文:https://www.cnblogs.com/xmzzp/p/6284300.html postgres 实现master, slave ,且master是多主. -------------- ...
- Emeditor V14注册码
Emeditor V14注册码 姓 名:ttrar.com 序 列 号:DKAZQ-R9TYP-5SM2A-9Z8KD-3E2RK
- 推荐一款jQuery ColorPicked 颜色拾取器插件
先看实现的效果图, 本文底部有完整demo 不想看我墨迹的可以跳过了^_^. 官网地址:http://www.eyecon.ro/colorpicker/#about 代码SVN 地址:https:/ ...
- (算法)Travel Information Center
题目: Aps Island has many cities. In the summer, many travellers will come to the island and attend fe ...
- Android 之 沉浸式状态栏及顶部状态栏背景色设置
现在很多应用都引用了沉浸式状态栏,如QQ,效果下图: 效果很酷炫,其实设置也很简单.但是,需要注意的是,这种效果只能在API19以及以上版本中才能够做到. 方法一: 首先,如果想让界面Activity ...
- SQL Server 之 修改时不允许保存更改
SQL Server错误提示:不允许保存更改. 您所做的更改要求删除并重新创建以下表.您对无法重新创建的表进行了更改或者启用了“阻止保存要求重新创建表的更改”选项. 修改数据库的数据结构,比如把var ...