Android将Activity打成jar包供第三方调用(解决资源文件不能打包的问题)

转载地址:http://blog.csdn.net/xiaanming/article/details/9257853

最近有一个需要,我们公司做了一个apk客户端,然后其他的公司可以根据自己的需要来替换里面的资源图片,文字等一些资源文件问题,我本来想这个简单,用两个工程直接替换里面的资源文件就行,老大说,这样子不好,如果要改需要改两个客户端,而且还麻烦,叫我将所有的Activity打成Jar包的形式,这样子我们改了里面的内容就直接发布Jar包出去,其他公司直接下载Jar来使用,这样子他们自己公司也能更好的维护。

所以我就想直接将Activity打成Jar包,可是在使用的过程中发现这样子根本行不通,因为如果Activity引用了布局文件的话,比如R.layout.XXX或者R.string.XXX,我们使用的时候会报资源ID未找到的异常,在官网上看到可以将另一个工程当做Libraryhttp://developer.android.com/tools/projects/projects-eclipse.html,可是这样子需要将源码给到人家,不能直接发布Jar包,貌似不是我要的那种情况,今天我教大家如果将Activity打成Jar包的形式

1.我们新建一个Android工程,取名为ActivityLibrary,这个就是等下我们需要打包成Jar的工程

注:MResource这个类很重要,主要是它的作用,利用反射根据资源名字获取资源ID(其实系统也自带了根据资源名字获取资源ID的方法getResources().getIdentifier("main_activity", "layout", getPackageName());第一个参数是资源的名字,第二个参数是资源的类型,例如layout, string等,第三个是包名字)

[java] view plaincopy

  1. package com.example.activitylibrary;
  2. import android.content.Context;
  3. /**
  4. * 根据资源的名字获取其ID值
  5. * @author mining
  6. *
  7. */
  8. public class MResource {
  9. public static int getIdByName(Context context, String className, String name) {
  10. String packageName = context.getPackageName();
  11. Class r = null;
  12. int id = 0;
  13. try {
  14. r = Class.forName(packageName + ".R");
  15. Class[] classes = r.getClasses();
  16. Class desireClass = null;
  17. for (int i = 0; i < classes.length; ++i) {
  18. if (classes[i].getName().split("\\$")[1].equals(className)) {
  19. desireClass = classes[i];
  20. break;
  21. }
  22. }
  23. if (desireClass != null)
  24. id = desireClass.getField(name).getInt(desireClass);
  25. } catch (ClassNotFoundException e) {
  26. e.printStackTrace();
  27. } catch (IllegalArgumentException e) {
  28. e.printStackTrace();
  29. } catch (SecurityException e) {
  30. e.printStackTrace();
  31. } catch (IllegalAccessException e) {
  32. e.printStackTrace();
  33. } catch (NoSuchFieldException e) {
  34. e.printStackTrace();
  35. }
  36. return id;
  37. }
  38. }

当我们的资源Id是一个数组的时候,我们要用下面的方法

[java] view plaincopy

  1. public static int[] getIdsByName(Context context, String className, String name) {
  2. String packageName = context.getPackageName();
  3. Class r = null;
  4. int[] ids = null;
  5. try {
  6. r = Class.forName(packageName + ".R");
  7. Class[] classes = r.getClasses();
  8. Class desireClass = null;
  9. for (int i = 0; i < classes.length; ++i) {
  10. if (classes[i].getName().split("\\$")[1].equals(className)) {
  11. desireClass = classes[i];
  12. break;
  13. }
  14. }
  15. if ((desireClass != null) && (desireClass.getField(name).get(desireClass) != null) && (desireClass.getField(name).get(desireClass).getClass().isArray()))
  16. ids = (int[])desireClass.getField(name).get(desireClass);
  17. }
  18. catch (ClassNotFoundException e) {
  19. e.printStackTrace();
  20. } catch (IllegalArgumentException e) {
  21. e.printStackTrace();
  22. } catch (SecurityException e) {
  23. e.printStackTrace();
  24. } catch (IllegalAccessException e) {
  25. e.printStackTrace();
  26. } catch (NoSuchFieldException e) {
  27. e.printStackTrace();
  28. }
  29. return ids;
  30. }

LibraryActivity这里面比较简单,一个Button,一个TextView,一个ImageView

[java] view plaincopy

  1. package com.example.activitylibrary;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.View;
  5. import android.view.View.OnClickListener;
  6. import android.widget.Button;
  7. import android.widget.TextView;
  8. import android.widget.Toast;
  9. public class LibraryActivity extends Activity {
  10. String msg = "我是来自Jar中的Activity";
  11. @Override
  12. protected void onCreate(Bundle savedInstanceState) {
  13. super.onCreate(savedInstanceState);
  14. setContentView(MResource.getIdByName(getApplication(), "layout", "activity_main"));
  15. TextView mTextView = (TextView) findViewById(MResource.getIdByName(getApplication(), "id", "textView1"));
  16. mTextView.setText(msg);
  17. Button mButton = (Button) findViewById(MResource.getIdByName(getApplication(), "id", "button1"));
  18. mButton.setText(msg);
  19. mButton.setOnClickListener(new OnClickListener() {
  20. @Override
  21. public void onClick(View v) {
  22. Toast.makeText(getApplication(), msg, Toast.LENGTH_SHORT).show();
  23. }
  24. });
  25. }
  26. }

Activity的布局

[html] view plaincopy

  1. <RelativeLayout 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. tools:context=".MainActivity" >
  6. <Button
  7. android:id="@+id/button1"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_alignParentLeft="true"
  11. android:layout_alignParentRight="true"
  12. android:layout_alignParentTop="true" />
  13. <TextView
  14. android:id="@+id/textView1"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:layout_alignParentLeft="true"
  18. android:layout_alignParentRight="true"
  19. android:layout_below="@+id/button1" />
  20. <ImageView
  21. android:id="@+id/imageView1"
  22. android:layout_width="wrap_content"
  23. android:layout_height="wrap_content"
  24. android:layout_alignParentBottom="true"
  25. android:layout_alignParentLeft="true"
  26. android:layout_alignParentRight="true"
  27. android:layout_below="@+id/textView1"
  28. android:layout_marginTop="28dp"
  29. android:src="@drawable/ic_launcher" />
  30. </RelativeLayout>

2.我们将ActivityLibrary工程打成Jar包。右键工程--->Export---->Java--->JAR file---->Next如下图

只勾选src目录,其他的都不勾选,如图

通过上面这几步我们就将Android工程打包好了

3.我们来使用刚刚打包好的Activity,我们还需要刚刚那个工程的资源文件,因为我们刚刚只打包了src,资源文件不能打包,因此我们需要自己拿出来,我们需要吧Library.jar加入到libs里面去,然后用到的资源文件,如果layout,string之类的拷贝到对应工程的地方去

这个工程一个MainActivity,里面一个按钮,点击按钮跳转到Library中的Activity中,比较简单我直接把代码贴上

[java] view plaincopy

  1. package com.example.androidlibraryinvoke;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. public class MainActivity extends Activity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.main);
  13. Button mButton = (Button) findViewById(R.id.button1);
  14. mButton.setOnClickListener(new OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. Intent intent = new Intent();
  18. intent.setClassName(getApplication(), "com.example.activitylibrary.LibraryActivity");
  19. startActivity(intent);
  20. }
  21. });
  22. }
  23. }

我们需要在AndroidManifest.xml注册LibraryActivity,否则报Activity找不到异常,总体来说就是这样子,这样子我们将Activity打成的Jar包和资源文件一起发出去,人家就可以调用可,如果你觉得我写的对你有帮助的话你就顶一下,谢谢!

代码下载

时间: 2024-08-28 23:34:57

Android将Activity打成jar包供第三方调用(解决资源文件不能打包的问题)的相关文章

Android 将Activity打成jar包 供第三方使用 彻底解决XML 图片 文字资源不可悲打入到jar包的问题!

做项目需要将程序打包成jar文件供第三方使用项目要求(将图片 文字资源写到到jar包中,第三方调用时,仅需要在AndroidManifest.xml配置下相应的Activity通过StartActivity方式拉起Activity):在网上找了好久,并依靠查看Android源码最终解决了问题 一:需要明白知识: 1.APK中的Res目录无法通过Eclipse的Export方式导入到jar包中 而Assert可以 2.Android程序在编译成APK时需要通过aapt将Res目录下的资源生成对应的

Android 将Activity及其他类打包成jar包供第三方调用

在开发java工程时,一个项目可能分为多个模块,为了实现模块间的解耦和独立,提高模块的复用性,通常将项目按模块分为多个java工程进行开发,最后通过jar包等工程依赖的方式实现系统集成,提高模块的耦合和复用. 现在开发Android项目通过实践和总结,发现这种方式特别有必要,比如开发一个android端的视频播放功能,肯定有播放和下载模块,如果不分开放在一个工程里面不断的添加新的功能,产品的每一个研发都不断的添加修改功能,最后维护越来越难,bug越来越多,并相互推诿,这种方式能避免这种情况,此为

Android 将Activity殴打jar包 对于由第三方使用 解决XML 图片 文本资源并不难过进入jar包装问题!

做项目需要打包成jar文件供第三方使用项目要求(将图片 文字资源写到到jar包中,第三方调用时,仅须要在AndroidManifest.xml配置下对应的Activity通过StartActivity方式拉起Activity):在网上找了好久.并依靠查看Android源代码终于攻克了问题 一:须要明确知识: 1.APK中的Res文件夹无法通过Eclipse的Export方式导入到jar包中 而Assert能够 2.Android程序在编译成APK时须要通过aapt将Res文件夹下的资源生成相应的

WEB应用打成jar包全记录

内容属原创,转载请注明出处 题外 由于项目的需求—不管是怎么产生的这个需求—总之,需要支持把一个web应用打成jar包供其他应用使用,这就有了下面的过程. 这个过程里用到了Spring和SpringMVC(用到的版本是3.1.4,后面略过此描述)的若干东东,如果不用这玩意的,请飘过. 要做些什么? 需要打包的这个Web应用包含下面这些内容: 静态资源,含 js.css.image 页面文件:jsp Jsp标签,含 tld文件和若干java代码 基于SpringMVC的其他若干Control和Se

将Android工程打成jar包之后对资源的调用。

Android工程不能完整的打包成jar包.这个主要是R文件导致的,但是我们可以将除了资源文件中的所有东西都打到jar包中.Activity.View等等类. 提供jar包的同时,还需要提供资源文件. 需要注意的是: 1.如果jar包中包含Activity中,一定要在引用的工程中注册 2.如果有资源文件,不能使用R.--  将资源文件拷贝到引用的工程中 使用以下类进行转换调用. public class MResource { public static int getIdByName(Cont

利用jar -cvf *.jar * 和直接islibrary 然后生成的jar包比较(Android中jar包封装及调用)

利用jar  -cvf  *.jar * 和直接islibrary 然后生成的jar包比较 jar  -cvf  *.jar *   会打包资源 即R.java.BuildConfing.java和MainActivity.java is  library只会把包MainActivity.java 百度:(但是还是觉得没有解决我的疑惑) 在android开发过程中,我们经常会有这种需求,自己开发一个类库jar包,提供给别人调用. 即把项目A封装成jar包,供项目B调用,而在项目B中调用项目A的a

Android 中jar包封装及调用-转

在android开发过程中,我们经常会有这种需求,自己开发一个类库jar包,提供给别人调用. 即把项目A封装成jar包,供项目B调用,而在项目B中调用项目A的activity的时候问题就出现了:找不到资源文件(异常:ERROR/AndroidRuntime(3341):Caused by: android.content.res.Resources$NotFoundException: Stringresource ID #0x7f060007).问题是,只能共享src文件夹下的代码,而不能共享

把自己的程序打成jar包,让别人调用

 我们写程序的时候往往需要把自己的程序打包成jar包,给第三方调用.Eclipse让我们非常方便的可以导出jar包.但是当程序里需要用到res里的资源时,往往就会出现问题.因为统自动生成的R类如果被打到jar包中后,就失去了索引资源的作用.导致封装成jar包的view无法获取对应资源.因为R类的属性值是在应用编译打包时由系统自动分配的.R类打包之后失效,实际是因为R类的内部类里面的属性失效,因为打包之后这些属性的值就固定了,但是实际项目中这些值是在编译时有系统自动分配的,无法在编译前固定. 本文

Android APK及导出JAR包的代码混淆

像Android开发基于java语言的,很容易被别人反编译出来,一下就相当于裸奔了,特别是用于商业用途的时候,防止反编译是必要的措施.而代码混淆是一种很好防止反编译的方式. 1.APK的代码混淆. 在eclipse的开发环境下,使用android SDK 自带的proguard混淆工具. 主要用到红线框中的两个文件. 在project.properties文件中,要指定混淆的文件.如图: 然后,详细的proguard-project.txt的写法如下: -dontwarn 是让指定包名不提示警告