android动态换肤系列3——从apk文件中获取Resources对象(上)
2016-02-29 16:54
453 查看
1、新建一个空的工程x,只把本工程的res文件覆盖过去,然后利用这个x生成apk。改名为“text.thinking”,并放在跟目录下。
读取x的Resources对象过程如下:
ResourcesActivity.java文件
package com.thinking.skintest;
import java.io.File;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.thinking.skintest.Read.IListener;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ResourcesActivity extends Activity implements IListener {
private Button btn_start;
private TextView txt_pk;
private TextView txt_res;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_resources);
btn_start = (Button) findViewById(R.id.btn_start);
txt_pk = (TextView) findViewById(R.id.txt_pk);
txt_res = (TextView) findViewById(R.id.txt_res);
btn_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
new Read().doRead(ResourcesActivity.this,
ResourcesActivity.this);
}
});
}
@Override
public void onReadPkName(final String pk_name) {
// TODO Auto-generated method stub
mHandler.post(new Runnable() {
@Override
public void run() {
txt_pk.setText(pk_name);
}
});
}
@Override
public void onReadRes(final int hash_code) {
mHandler.post(new Runnable() {
@Override
public void run() {
txt_res.setText(hash_code + "");
}
});
}
}
class Read {
public static ExecutorService pool = Executors.newFixedThreadPool(1);
private static String SDCardPath = Environment
.getExternalStorageDirectory().getPath();
public interface IListener {
public void onReadPkName(String pk_name);
public void onReadRes(int hash_code);
}
public void doRead(final Context context, final IListener listener) {
pool.execute(new Runnable() {
@Override
public void run() {
// 制作text.thinking压缩文件,文件目录与本apk相同
File file = new File(SDCardPath + "/" + "text.thinking");
// 获取text.thinking的packageName
PackageManager mPm = context.getPackageManager();
PackageInfo mInfo = mPm.getPackageArchiveInfo(
file.getAbsolutePath(), PackageManager.GET_ACTIVITIES);
String pk_name = mInfo.packageName;
listener.onReadPkName(pk_name);// 需要READ_EXTERNAL_STORAGE权限
// 通过反射获取text.thinking的参数
AssetManager assetManager = null;
try {
assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod(
"addAssetPath", String.class);
addAssetPath.invoke(assetManager, file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
// 用本地Resources的参数(屏幕、配置信息等)实例化
DisplayMetrics disp = context.getResources()
.getDisplayMetrics();
Configuration config = context.getResources()
.getConfiguration();
Resources newResource = new Resources(assetManager, disp,
config);
listener.onReadRes(newResource.hashCode());
}
});
}
}
activity_resources.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start" />
<TextView
android:id="@+id/txt_pk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="@+id/txt_res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
运行结果
读取x的Resources对象过程如下:
ResourcesActivity.java文件
package com.thinking.skintest;
import java.io.File;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.thinking.skintest.Read.IListener;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ResourcesActivity extends Activity implements IListener {
private Button btn_start;
private TextView txt_pk;
private TextView txt_res;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_resources);
btn_start = (Button) findViewById(R.id.btn_start);
txt_pk = (TextView) findViewById(R.id.txt_pk);
txt_res = (TextView) findViewById(R.id.txt_res);
btn_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
new Read().doRead(ResourcesActivity.this,
ResourcesActivity.this);
}
});
}
@Override
public void onReadPkName(final String pk_name) {
// TODO Auto-generated method stub
mHandler.post(new Runnable() {
@Override
public void run() {
txt_pk.setText(pk_name);
}
});
}
@Override
public void onReadRes(final int hash_code) {
mHandler.post(new Runnable() {
@Override
public void run() {
txt_res.setText(hash_code + "");
}
});
}
}
class Read {
public static ExecutorService pool = Executors.newFixedThreadPool(1);
private static String SDCardPath = Environment
.getExternalStorageDirectory().getPath();
public interface IListener {
public void onReadPkName(String pk_name);
public void onReadRes(int hash_code);
}
public void doRead(final Context context, final IListener listener) {
pool.execute(new Runnable() {
@Override
public void run() {
// 制作text.thinking压缩文件,文件目录与本apk相同
File file = new File(SDCardPath + "/" + "text.thinking");
// 获取text.thinking的packageName
PackageManager mPm = context.getPackageManager();
PackageInfo mInfo = mPm.getPackageArchiveInfo(
file.getAbsolutePath(), PackageManager.GET_ACTIVITIES);
String pk_name = mInfo.packageName;
listener.onReadPkName(pk_name);// 需要READ_EXTERNAL_STORAGE权限
// 通过反射获取text.thinking的参数
AssetManager assetManager = null;
try {
assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod(
"addAssetPath", String.class);
addAssetPath.invoke(assetManager, file.getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
}
// 用本地Resources的参数(屏幕、配置信息等)实例化
DisplayMetrics disp = context.getResources()
.getDisplayMetrics();
Configuration config = context.getResources()
.getConfiguration();
Resources newResource = new Resources(assetManager, disp,
config);
listener.onReadRes(newResource.hashCode());
}
});
}
}
activity_resources.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start" />
<TextView
android:id="@+id/txt_pk"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="@+id/txt_res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
运行结果
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories