Android 反射调用资源和id

本文介绍利用反射调用资源和id

提出问题:

app有一种叫应用墙的广告,应用墙是在你的程序中弹出一个Activity来展示广告,比如豌豆广点通等,集成的时候需要将资源通过复制添加到自己的项目中,但是app墙的代码是封装好的jar代码。不是源码,看不到,也不能修改。那么jar中的代码是如何加载本地资源的呢?

自己的项目中加载资源的时候都是通过本项目的R文件来初始化资源,R文件是你自己的项目的R文件,和项目有关,如果第三方的jar文件中使用的R是来第三方SDK项目中的资源R,代码更换了项目之后铁定了是找不到你复制过来的资源的。那么这时候就需要通过特殊的方式来加载资源了,以便于调用在被集成的app中的资源。

通过原始的java反射机制的方式调用资源:

这只是一种方式,还有其他的方式。

IDHelper.java

public class IDHelper {
	public static int getLayout(Context mContext, String layoutName) {
		return ResourceHelper.getInstance(mContext).getLayoutId(layoutName);
	}

	public static int getViewID(Context mContext, String IDName) {
		return ResourceHelper.getInstance(mContext).getId(IDName);
	}

	public static int getDrawable(Context context, String drawableName) {
		return ResourceHelper.getInstance(context).getDrawableId(drawableName);
	}

	public static int getAttr(Context context, String attrName) {
		return ResourceHelper.getInstance(context).getAttrId(attrName);
	}

	public static int getString(Context context, String stringName) {
		return ResourceHelper.getInstance(context).getStringId(stringName);
	}

}

ResourceHelper.java

public class ResourceHelper {
	private static ResourceHelper mResource = null;
	private static String mPackagename = null;
	private static Class<?> mLayout = null;
	private static Class<?> mDrawable = null;
	private static Class<?> mID = null;
	private static Class<?> mString = null;
	private static Class<?> mAttr = null;

	public static ResourceHelper getInstance(Context context) {
		if (mResource == null) {
			mPackagename = (mPackagename == null ? context.getPackageName()
					: mPackagename);
			mResource = new ResourceHelper(mPackagename);
		}
		return mResource;
	}

	public ResourceHelper(String packageName) {
		try {
			mLayout = Class.forName(packageName + ".R$layout");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			mDrawable = Class.forName(packageName + ".R$drawable");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			mID = Class.forName(packageName + ".R$id");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			mString = Class.forName(packageName + ".R$string");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			mAttr = Class.forName(packageName + ".R$attr");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

	}

	private int getResourceId(Class<?> classType, String resourceName) {
		if (classType == null) {
			throw new IllegalArgumentException(
					"ResClass is not initialized. Please make sure you have added neccessary resources. Also make sure you have "
							+ mPackagename
							+ ".R$* configured in obfuscation. field="
							+ resourceName);
		}
		try {
			Field field = classType.getField(resourceName);
			return field.getInt(resourceName);
		} catch (Exception e) {
			e.printStackTrace();
			Log.e("ResourceHelper",
					"Error getting resource. Make sure you have copied all resources (res/) from SDK to your project.");
		}
		return -1;
	}

	//
	public int getDrawableId(String resourceName) {
		return getResourceId(mDrawable, resourceName);
	}

	public int getLayoutId(String resourceName) {
		return getResourceId(mLayout, resourceName);
	}

	public int getId(String resourceName) {
		return getResourceId(mID, resourceName);
	}

	public int getStringId(String resourceName) {
		return getResourceId(mString, resourceName);
	}

	public int getAttrId(String resourceName) {
		return getResourceId(mAttr, resourceName);
	}

}

使用:

使用的时候不需要通过R来调用资源

public class MainActivity extends ActionBarActivity {
	private Button mButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(IDHelper.getLayout(getApplicationContext(),
				"activity_main"));//字符串是layout文件的名字
		initView();
	}

	private void initView() {
		mButton = (Button) findViewById(IDHelper.getViewID(
				getApplicationContext(), "button1"));
		mButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				Toast.makeText(getApplicationContext(), "HelloWorld",
						Toast.LENGTH_LONG).show();//字符串是控件的id
			}
		});
	}
}

通过Android API 的通过反射获取id的方法

Context.getResources().getIdentifier("activity_main", "layout",
                paramContext.getPackageName()); 
时间: 2024-08-02 11:04:19

Android 反射调用资源和id的相关文章

Android反射机制实现与原理

本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 在Java中的反射机制,被称为Reflection(大家看到这个单词,第一个想法应该就是去开发文档中

大叔也说Xamarin~Android篇~调用远程API接口,发POST请求

Xamarin我们在上节已经教大家如何去部署它的环境了,今天来说一个实际的例子,使用android客户调用.net web api的一个接口,并发送POST请求,当服务端回到请求后做出响应,客户端android将响应的内容输出,并跳换到别一个Activity页面,在新视图上加载网页内容到webView控件上,整个流程结束! 一 在主页面上添加几个表单元素,账号,密码,登陆按钮,并在Activity类的OnCreate方法中为它们赋值,并添加按钮的click事件 protected overrid

如何制作Jar包并在android中调用jar包

android制作jar包: 新建android工程,然后右击,点击导出,选择导出类型为Java下的JAR file,在java file specification 中不要选择androidmanifest.xml和res文件夹,就可以了.否则在调用jar包的时候会出现“Error generating final archive: Found duplicate file for APK: AndroidManifes”这个错误. 如果在android用调用jar包,需要在工程的属性的Jav

在Android中调用C#写的WebService(附源代码)

由于项目中要使用Android调用C#写的WebService,于是便有了这篇文章.在学习的过程中,发现在C#中直接调用WebService方便得多,直接添加一个引用,便可以直接使用将WebService当做一个对象使用,利用Vs2010中的代码提示功能就能爽歪歪地把想要的东西全部点出来.在Android调用,麻烦了一点,但是也还好.主要是我们需要自己在代码中确定要调用WebService的方法名是什么,要传给WebService什么参数以及对应的参数名,另外,一些额外的信息比如soap的版本号

在C++中反射调用.NET(二)

反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C++与.NET程序集之间传递复杂对象. 先看看.NET程序集的一个返回对象的方法: public IUserInfo GetUserByID(int userId) { IUserInfo userinfo= EntityBuilder.CreateEntity<IUserInfo>(); user

android怎样调用@hide和internal API

android怎样调用@hide和internal API 2012-12-11 16:21 8772人阅读 评论(3) 收藏 举报  分类: Android开发(277)  Android有两种类型的API是不能经由SDK访问的. 第一种是位于com.android.internal包中的API.我将称之为internal API.第二种API类型是一系列被标记为@hide属性的类和方法.从严格意义上来讲,这不是一个单一的API,而是一组小的被隐藏的API,但我仍将其假设为一种API,并称之为

38. Android 反射资源工具ReflectionUtil

38. Android 反射资源工具ReflectionUtil Android 反射资源工具ReflectionUtil 工具代码 工具使用 工具代码 ReflectionUtil public class ReflectionUtil { public enum ResourcesType { styleable, style, string, mipmap, menu, layout, integer, id, drawable, dimen, color, bool, attr, ani

在Android中使用Android Ksoap2调用WebService

一.WebService介绍 WebService是基于SOAP协议可实现web服务器与web服务器之间的通信,因采用SOAP协议传送XML数据具有平台无关性,也是成为解决异构平台之间通信的重要解决方案,比如Java平台与.net平台之间.因此在web应用中有着举足轻重的作用,很多机构.组织都在各自平台上对外发布了WebService(例如:天气预报.航班信息.股市行情等等),这样任何平台和客户都可以享受到这些服务,当然有些是要付费的. 二.Android ksoap2组件 对于Android端

Android:调用其他程序中的activity和Permission Denial: starting Intent 错误解决办法

今天想调试多个task中栈的情况,在测试程序中调用另一个程序的activity, 代码片段如下: [java] view plaincopy btnStartX=(Button)findViewById(R.id.btnStartX); btnStartX.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stu