最近有一個需要,我們公司做了一個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
package com.example.activitylibrary;
import android.content.context;
/**
* 根據資源的名字擷取其id值
* @author mining
*
*/
public class mresource {
public static int getidbyname(context context, string classname, string name) {
string packagename = context.getpackagename();
class r = null;
int id = 0;
try {
r = class.forname(packagename + ".r");
class[] classes = r.getclasses();
class desireclass = null;
for (int i = 0; i < classes.length; ++i) {
if (classes[i].getname().split("\\$")[1].equals(classname)) {
desireclass = classes[i];
break;
}
}
if (desireclass != null)
id = desireclass.getfield(name).getint(desireclass);
} catch (classnotfoundexception e) {
e.printstacktrace();
} catch (illegalargumentexception e) {
} catch (securityexception e) {
} catch (illegalaccessexception e) {
} catch (nosuchfieldexception e) {
}
return id;
}
}
當我們的資源id是一個數組的時候,我們要用下面的方法
public static int[] getidsbyname(context context, string classname, string name) {
string packagename = context.getpackagename();
class r = null;
int[] ids = null;
try {
r = class.forname(packagename + ".r");
class[] classes = r.getclasses();
class desireclass = null;
for (int i = 0; i < classes.length; ++i) {
if (classes[i].getname().split("\\$")[1].equals(classname)) {
desireclass = classes[i];
break;
}
if ((desireclass != null) && (desireclass.getfield(name).get(desireclass) != null) && (desireclass.getfield(name).get(desireclass).getclass().isarray()))
ids = (int[])desireclass.getfield(name).get(desireclass);
catch (classnotfoundexception e) {
e.printstacktrace();
} catch (illegalargumentexception e) {
} catch (securityexception e) {
} catch (illegalaccessexception e) {
} catch (nosuchfieldexception e) {
return ids;
}
libraryactivity這裡面比較簡單,一個button,一個textview,一個imageview
import android.app.activity;
import android.os.bundle;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.textview;
import android.widget.toast;
public class libraryactivity extends activity {
string msg = "我是來自jar中的activity";
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(mresource.getidbyname(getapplication(), "layout", "activity_main"));
textview mtextview = (textview) findviewbyid(mresource.getidbyname(getapplication(), "id", "textview1"));
mtextview.settext(msg);
button mbutton = (button) findviewbyid(mresource.getidbyname(getapplication(), "id", "button1"));
mbutton.settext(msg);
mbutton.setonclicklistener(new onclicklistener() {
@override
public void onclick(view v) {
toast.maketext(getapplication(), msg, toast.length_short).show();
});
activity的布局
[html] view
<relativelayout 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"
tools:context=".mainactivity" >
<button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignparentleft="true"
android:layout_alignparentright="true"
android:layout_alignparenttop="true" />
<textview
android:id="@+id/textview1"
android:layout_below="@+id/button1" />
<imageview
android:id="@+id/imageview1"
android:layout_alignparentbottom="true"
android:layout_below="@+id/textview1"
android:layout_margintop="28dp"
android:src="@drawable/ic_launcher" />
</relativelayout>
2.我們将activitylibrary工程打成jar包。右鍵工程--->export---->java--->jar file---->next如下圖
隻勾選src目錄,其他的都不勾選,如圖
通過上面這幾步我們就将android工程打包好了
3.我們來使用剛剛打包好的activity,我們還需要剛剛那個工程的資源檔案,因為我們剛剛隻打包了src,資源檔案不能打包,是以我們需要自己拿出來,我們需要吧library.jar加入到libs裡面去,然後用到的資源檔案,如果layout,string之類的拷貝到對應工程的地方去
這個工程一個mainactivity,裡面一個按鈕,點選按鈕跳轉到library中的activity中,比較簡單我直接把代碼貼上
package com.example.androidlibraryinvoke;
import android.content.intent;
public class mainactivity extends activity {
setcontentview(r.layout.main);
button mbutton = (button) findviewbyid(r.id.button1);
intent intent = new intent();
intent.setclassname(getapplication(), "com.example.activitylibrary.libraryactivity");
startactivity(intent);
我們需要在androidmanifest.xml注冊libraryactivity,否則報activity找不到異常,總體來說就是這樣子,這樣子我們将activity打成的jar包和資源檔案一起發出去,人家就可以調用可,如果你覺得我寫的對你有幫助的話你就頂一下,謝謝!
代碼下載下傳