当前位置: 代码迷 >> Android >> android应用Theme(2)
  详细解决方案

android应用Theme(2)

热度:81   发布时间:2016-04-28 05:18:28.0
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();			}		}	}}





  相关解决方案