插件化-皮肤

1、清单文件

android:sharedUserId="com.zyh.skinplugin"

2、视图文件

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     android:id="@+id/ll"
 7     android:background="@drawable/spring_main_bg"
 8     tools:context=".MainActivity" >
 9
10     <ImageButton
11         android:id="@+id/ib"
12         android:layout_width="wrap_content"
13         android:layout_height="wrap_content"
14         android:layout_gravity="right"
15         android:layout_marginRight="10dp"
16         android:src="@drawable/ic_launcher"
17         />
18
19 </LinearLayout>
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical" >
 6     <ListView
 7         android:layout_width="wrap_content"
 8         android:layout_height="wrap_content"
 9         android:id="@+id/lv"
10         />
11
12 </LinearLayout>

3、java文件

  1 package com.zyhitheima.plugin_main;
  2
  3 import java.lang.reflect.Field;
  4 import java.util.ArrayList;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Map;
  8
  9 import dalvik.system.PathClassLoader;
 10
 11 import android.os.Bundle;
 12 import android.app.Activity;
 13 import android.content.Context;
 14 import android.content.pm.PackageInfo;
 15 import android.content.pm.PackageManager;
 16 import android.content.pm.PackageManager.NameNotFoundException;
 17 import android.view.Gravity;
 18 import android.view.Menu;
 19 import android.view.View;
 20 import android.view.View.OnClickListener;
 21 import android.widget.AdapterView;
 22 import android.widget.AdapterView.OnItemClickListener;
 23 import android.widget.ImageButton;
 24 import android.widget.LinearLayout;
 25 import android.widget.ListView;
 26 import android.widget.PopupWindow;
 27 import android.widget.SimpleAdapter;
 28 import android.widget.Toast;
 29
 30 public class MainActivity extends Activity implements OnClickListener, OnItemClickListener {
 31     private ImageButton ib;
 32     private LinearLayout ll;
 33     private List<Map<String, Object>> data;
 34     @Override
 35     protected void onCreate(Bundle savedInstanceState) {
 36         super.onCreate(savedInstanceState);
 37         setContentView(R.layout.activity_main);
 38
 39         ib = (ImageButton) findViewById(R.id.ib);
 40         ll = (LinearLayout) findViewById(R.id.ll);
 41
 42         data = new ArrayList<Map<String, Object>>();
 43
 44         ib.setOnClickListener(this);
 45
 46
 47     }
 48     @Override
 49     public void onClick(View v) {
 50         View view = View.inflate(this, R.layout.popup_window, null);
 51         ListView lv = (ListView) view.findViewById(R.id.lv);
 52
 53         PopupWindow popupWindow = new PopupWindow(this);
 54         popupWindow.setContentView(view);
 55         popupWindow.setBackgroundDrawable(getResources().getDrawable(R.drawable.pw_bg));
 56         popupWindow.setFocusable(true);//设置焦点
 57
 58         int[] location = new int[2];
 59         ib.getLocationInWindow(location);//获取ib的坐标
 60
 61         //搜索插件
 62         data = findPlugins();
 63
 64         if(data.size() == 0){
 65             Toast.makeText(this, "hello world", 0).show();
 66             return;
 67         }
 68
 69         SimpleAdapter adapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_1, new String[]{"label"}, new int[]{android.R.id.text1});
 70         lv.setAdapter(adapter);
 71
 72         lv.setOnItemClickListener(this);
 73
 74         popupWindow.setWidth(100);
 75         popupWindow.setHeight(data.size() * 40);
 76         popupWindow.showAtLocation(ib, Gravity.LEFT|Gravity.TOP, location[0], location[1]+ib.getHeight());
 77     }
 78     private List<Map<String, Object>> findPlugins() {
 79         List<Map<String, Object>> plugins = new ArrayList<Map<String, Object>>();
 80         //包管理器
 81         PackageManager pm = this.getPackageManager();
 82         List<PackageInfo> installPackages = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);//获取所有安装的package包
 83         for(PackageInfo info : installPackages){
 84             String pkgName = info.packageName;
 85             String sharedUserId = info.sharedUserId;
 86             if(sharedUserId == null || !sharedUserId.equals("com.zyh.skinplugin") || pkgName.endsWith(this.getPackageName())){
 87                 continue;
 88             }
 89
 90             String label = (String) pm.getApplicationLabel(info.applicationInfo);
 91
 92             Map<String, Object> map = new HashMap<String, Object>();
 93             map.put("label", label);
 94             map.put("pkgName", pkgName);
 95             plugins.add(map);
 96         }
 97         return plugins;
 98     }
 99     @Override
100     public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
101         String pkgName = (String) data.get(position).get("pkgName");
102         Context plugContext = null;
103         try {
104             plugContext = this.createPackageContext(pkgName, CONTEXT_IGNORE_SECURITY|CONTEXT_INCLUDE_CODE);
105         } catch (Exception e) {
106             // TODO Auto-generated catch block
107             e.printStackTrace();
108         }
109
110         try {
111             int bgId = getBgIdByPkgName(pkgName, plugContext);
112             //ll.setBackgroundDrawable(plugContext.getResources().getDrawable(bgId));
113             ll.setBackground(plugContext.getResources().getDrawable(bgId));
114         } catch (Exception e) {
115             // TODO Auto-generated catch block
116             e.printStackTrace();
117         }
118     }
119     private int getBgIdByPkgName(String pkgName, Context plugContext) throws Exception{
120         PathClassLoader pathClassLoader = new PathClassLoader(plugContext.getPackageResourcePath(), ClassLoader.getSystemClassLoader());
121         Class<?> forName = Class.forName(pkgName + ".R$drawable",true,pathClassLoader);
122         Field[] declaredFields = forName.getDeclaredFields();
123         for(Field field : declaredFields){
124             if(field.getName().contains("main_bg")){
125                 int index = 0;
126                 index = field.getInt(R.drawable.class);
127                 return index;
128             }
129         }
130         return 0;
131     }
132
133 }

4、测试应用即插件的清单配置

1   <activity
2             android:name="com.zyhitheima.plugin_sumer.MainActivity"
3             android:label="@string/app_name" >
4             <intent-filter>
5                 <action android:name="com.zyhitheima.plugin_sumer" />
6
7                 <category android:name="android.intent.category.DEFAULT" />
8             </intent-filter>
9         </activity>

注意它的action 是包名,category使用default

时间: 2024-10-24 17:48:51

插件化-皮肤的相关文章

Android 插件化开发-主题皮肤更换

参考 http://www.2cto.com/kf/201501/366859.html 本项目是以插件化开发思想进行的,主要工作和代码如下 资源文件,这里以color资源为例 1.首先我们需要准备一个皮肤包,这个皮肤包里面不会包含任何Activity,里面只有资源文件,这里我为了简单,仅仅加入一个color.xml(其实就相当于Android系统中的framework_res.apk) <!--?xml version="1.0" encoding="utf-8&qu

Android 插件化 动态升级

最新内容请见原文:Android 插件化 动态升级 不少朋友私信以及 Android开源交流几个 QQ 群 中都问到这个问题,这里简单介绍下 1.作用 大多数朋友开始接触这个问题是因为 App 爆棚了,方法数超过了一个 Dex 最大方法数 65535 的上限,从这个介绍中也知道可以通过多个 Dex 来解决这个问题,因而便有了插件化的概念,将一个 App 划分为多个插件(Dex或相关格式)常用的其他解决方法还包括:删无用代码,用 H5 代替部分逻辑,买付费版的 Proguard插件化的其他作用包括

Android插件化的思考——仿QQ一键换肤,思考比实现更重要!

Android插件化的思考--仿QQ一键换肤,思考比实现更重要! 今天群友希望写一个关于插件的Blog,思来想去,插件也不是很懂,只是用大致的思路看看能不能模拟一个,思路还是比较重要的,如果你有兴趣的话,也可以加群:555974449,你也可以说出你想看的Blog哦,嘿嘿!好的,不多说,我们进入正题: 关于QQ的换肤,他们的实现思路我不是很清楚,但是你可以看一下这张换肤的截图 我们想使用哪个主题就直接下载就好了,这一实现的过程我们大致的可以猜想: 首选是下载到本地指定文件夹,然后通过插件加载到我

Android插件化探索(二)资源加载

前情提要 在探索资源加载方式之前,我们先来看看上一篇中没细讲的东西.还没看过的建议先看上一篇Android插件化探索(一)类加载器DexClassLoader. PathClassLoader和DexClassLoader的区别 DexClassLoader的源码如下: public class DexClassLoader extends BaseDexClassLoader { //支持从任何地方的apk/jar/dex中读取 public DexClassLoader(String dex

android app 的插件化、组件化、模块化开发-2

Android 插件化 ——指将一个程序划分为不同的部分,比如一般 App的皮肤样式就可以看成一个插件 Android 组件化 ——这个概念实际跟上面相差不那么明显,组件和插件较大的区别就是:组件是指通用及复用性较高的构件,比如图片缓存就可以看成一个组件被多个 App共用 插件的方式只有三种:1,apk安装,2,apk不安装,3,dex包 滴滴插件化项目VirtualAPK开源!https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=22474

怎样将「插件化」接入到项目之中?

本期移动开发精英社群讨论的主题是「插件化」,上网查了一下,发现一篇 CSDN 博主写的文章<Android 使用动态载入框架DL进行插件化开发>.此处引用原作者的话: 随着应用的不断迭代,应用的体积不断增大,项目越来越臃肿,冗余添加.项目新功能的加入,无法确定与用户匹配性,发生严重异常往往牵一发而动全身,仅仅能紧急公布补丁版本号,强制用户进行更新.结果频繁的更新.反而easy减少用户使用黏性,或者是公司业务的不断发展,同系的应用越来越多,传统方式须要通过用户量最大的主项目进行引导下载并安装.

android插件化-apkplug从宿主启动插件Activity-06

插件是一个apk文件它存在自己的Activity界面和UI显示,本节将讲解如何配置插件的启动Activity以及怎样从宿主启动它. 一 配置插件apk的对外启动Activity (内部activity不需要配置) 与普通app不同,插件AndroidManifest.xml配置在apkplug框架中是无效的,我们需要在plugin.xml里面配置才能被apkplug所识别 具体设置属性为 Bundle-Activity="xxx.xxx.xxx.Activity" 只有设置为Bundl

android插件化-apkplug中OSGI服务基本原理-08

我们提供 apkplug 下OSGI使用demo 源码托管地址为 http://git.oschina.net/plug/OSGIService 一 OSGI与android Service 异同点 OSGI服务与android Service概念差不多也是Service ,Client 关系. android Service接口  --service.AIDL OSGI接口                --java interface 所以android 进程间通信Service只能传递序列

Asp.Net MVC 插件化开发简化方案

Web 管理系统可以庞大到不可想像的地方,如果想就在一个 Asp.Net MVC 项目中完成开发,这个工程将会变得非常庞大,协作起来也会比较困难.为了解决这个问题,Asp.Net MVC 引入了 Areas 的概念,将模块划分到 Area 中去--然而 Area 仍然是主项目的一部分,多人协作的时候仍然很容易造成 .csproj 项目文件的冲突. 对于这类系统,比较好的解决办法是采用 SOA 的方式,把一个大的 Web 系统划分成若干微服务,通过一个含授权中心的 Web 集散框架组织起来.不过这