標籤:android jar
在開發java工程時,一個項目可能分為多個模組,為了實現模組間的解耦和獨立,提高模組的複用性,通常將項目按模組分為多個java工程進行開發,最後通過jar包等工程依賴的方式實現系統整合,提高模組的耦合和複用。
現在開發Android項目通過實踐和總結,發現這種方式特別有必要,比如開發一個android端的視頻播放功能,肯定有播放和下載模組,如果不分開放在一個工程裡面不斷的添加新的功能,產品的每一個研發都不斷的添加修改功能,最後維護越來越難,bug越來越多,並相互推諉,這種方式能避免這種情況,此為有點一。其二呢,下載模組是很多APP都會用到的模組,將其獨立出來不斷的完善和最佳化,可以變成一個組件給不同的APP使用,這就提高了模組的代碼的解耦,提高的複用性,提高的工作效率,好處大大的哦。
由於Android的特殊性,android不僅有java檔案還有res檔案,需要研究如何將資源檔以及Activity檔案打包成jar檔案供其他項目調用,最終多方嘗試,找到如下兩種解決方案。
方案一:
根據Android的官方文檔,將其中一個項目設定為引用庫,在另一個項目中添加這個庫的引用。
簡單的做法是
在被引用項目TestJar中的project.properties中添加一行
android.library=true
在引用的項目TestMain的project.properties中添加
android.library=false android.library.reference.1=../TestJar
其中1表示引用包的序號,“../TestJar”表示引用項目的路徑
在Eclipse中操作具體做法如下:
- 把普通的android project設定成庫項目
庫項目也是一個標準的Android項目,因此你先建立一個普通的Android項目,這個項目可以起任何的名稱,任何的包名,設定其他需要設定的欄位等。
接著把項目設定成庫項目,步驟如下:
1)在Package Explorer中,滑鼠右鍵專案檔夾(TestJar),點擊Properties。
2)在Properties視窗選擇”Android“,Library屬性顯示在右下邊。
3)把”is Library“單選框選上,在點擊Apply。
4)點擊OK關閉Properties。
這時,這個項目就變成庫項目了,當然純的java項目也可以變成庫項目,非常簡單,執行上面四步就OK了。其他程式項目就可以引用這個庫項目了。
引用庫項目
如果你開發的應用程式想要調用庫項目中的代碼和資源,也easy哦,引用步驟如下:
1)在Package Explorer中,滑鼠右鍵專案檔夾(TestJar),點擊Properties。
2)在Properties視窗選擇”Android“,Library屬性顯示在右下邊。
3)點擊Add,開啟了Project Selection對話方塊。
4)從可用的庫項目列表中選擇要添加的庫項目,點擊OK。
5)對話方塊關閉之後點擊Apply,(在Properties視窗)。
6)點擊OK,關閉Properties視窗。
完成以上六步,Eclipse會重建項目,把庫項目中的內同包含進去。
- 如果你想增加多個庫項目的引用,使用up和down可以設定他們的相對的優先順序和合并順序。工具在合并引用的庫的時候順序是從低優先順序(列表的下面)到高優先順序(列表的上面)。 如果不只一個庫定義了相同的資源ID,這個工具選擇資源時會選擇高優先順序的資源。應用程式自身擁有最高的優先順序。
方案二:
通過匯出JAR包的方式供給其他項目去引用,沒有資源套件就不多說了直接匯出jar包就可以直接引用,下面說一下在有資源套件存在的時候打包Jar及引用方式。
實現步驟:
- 我們建立一個工程TestJar,這個就是等下我們要打包成jar工程
- 注意:MResource這個類很重要,主要是它的作用,利用反射根據資源名字擷取資源ID(其實系統也內建了根據資源名字擷取資源ID的方法getResources().getIdentifier("main_activity", "layout", getPackageName());第一個參數是資源的名字,第二個參數是資源的類型,例如layout, string等,第三個是包名字)
- MRsource.java代碼如下:
import android.content.Context;/** * 根據資源的名字擷取其ID值 * * @author yangzy */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) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } return id; }}
import android.content.Context;public class Statistics {public static Statistics mStatistics;public static Context mContext;public static Statistics getInstance() {if (mStatistics == null) {mStatistics = new Statistics();}return mStatistics;}public void init(Context context) {this.mContext = context;System.out.println("--Statistics---init--");}public void Login(int num) {System.out.println("--Statistics---" + num);}}
- TestUtilJar.java實現比較簡單一個圖片點擊後彈出一個Toast
import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.ImageView;import android.widget.Toast;public class TestUtilJar extends Activity { private ImageView imageView; private Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(MResource.getIdByName(getApplication(), "layout", "jar_activity_main")); context = this; imageView = (ImageView) findViewById(MResource.getIdByName(getApplication(), "id", "jar_imageView")); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText( context, "jar = " + getApplication().getString( MResource.getIdByName(getApplication(), "string", "jar_test_name")), Toast.LENGTH_SHORT).show(); } }); }}
- 布局檔案如下:
<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" android:background="#00eeff" tools:context=".MainActivity" > <ImageView android:id="@+id/jar_imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:layout_marginBottom="80dp" android:src="@drawable/photo" /></RelativeLayout>
- 將TestJar以Jar包形式匯出,出去一切資源檔,只匯出源碼
6、將匯出的testjar1.jar匯入到要引用的工程中,先複製到libs下面
最關鍵一步,將TestJar中引用到的資源檔全部拷貝到TestMain中去,這樣就可以順利的引用資源檔了,還有要用到Jar包中的Activity也需要再TestMain的AndroidManifest.xml配置對應包名的Activity。
- 在TestMain中引用
package com.example.testmain;import com.example.testjar.TestUtilJar;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button1); button.setOnClickListener(this);Statistics.getInstance().init(this);Statistics.getInstance().Login(19911019); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.button1: Intent intent = new Intent(this, TestUtilJar.class); startActivity(intent); break; } }}
同時在Manifest中註冊TestUtilJar 這個Activity
<activity
android:name="com.example.selfjar.TestUtilJar"
>
</activity>
</pre>
方案一是官方提供的方法應該比較好適合自己公司開發和引用開原始碼,但是有的時候是需要給第三方公司提供支援的,當然這個時候不想他們看到我們的原始碼,這時候採用方案二是比較理想的。
Android 將Activity及其他類打包成jar包供第三方調用