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 ...
随机推荐
- swift3.0:NSURLSession的使用
一.说明 NSURLSession是OC中的会话类,在Swift中变成URLSession类,它们的实现方式是一样的,下面的示例就Swift语法进行讲解和介绍. 二.介绍: URLSession 类支 ...
- windows server 2012将计算机图标添加到桌面
windows server 2012系统安装完以后桌面默认只有回收站一个图标,如何将window常用的图标(计算机.控制面板.网络.用户文件)的图标添加到桌面呢,下面为作者本人亲测.操作简单至极. ...
- Go语言之进阶篇爬百度贴吧并发版
1.爬百度贴吧并发版 示例: package main import ( "fmt" "net/http" "os" "strco ...
- go语言之进阶篇关闭channel
1.关闭channel package main import ( "fmt" ) func main() { ch := make(chan int) //创建一个无缓存chan ...
- win7基于mahout推荐之用户相似度计算
http://www.douban.com/note/319219518/?type=like win7基于mahout推荐之用户相似度计算 2013-12-03 09:19:11 事情回到半年 ...
- [转]PostgreSQL Replication之扩展与BDR
原文:https://www.cnblogs.com/xmzzp/p/6284300.html postgres 实现master, slave ,且master是多主. -------------- ...
- wamp因配置错误而导致apache无法启动的问题
在使用wamp搭建一个PHP项目环境时,却出现了apache无法启动的问题 通过查看window的错误日志才发现apache出现了错误 错误的原因说的很清楚,是因为配置文件中的Director ...
- google test框架与eclipse插件
1. https://github.com/google/googletest (google的测试框架) 2. eclipse测试框架插件 https://github.com/xgsa/cd ...
- Android 基本 Jackson Marshalling(serialize)/Unmarshalling(deserialize)
本文内容 基本 Jack Marshalling 忽略属性 忽略 Null 字段 改变字段名字 基本 Jackson Marshalling 把 JSON 解析成 JsonNode Unmarshal ...
- Ado.Net,关于DataSet和DataTable
DataSet和DataTable的 区别与联系 1.简要说明二者关系 在我们编写代码的时候从数据库里取出数据,填充到dataset里,再根据表的名字,实例化到 DataTable 中. ●注意如下 ...