使用Eclipse将Android项目打Jar包

时间:2021-08-19 09:13:14


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


这两天在学习将自己的Android项目打成Jar包,但是测试自己的Jar包的时候会提示找不到Activity的layout,我打Jar包的时候是把资源文件也放进来了,这样是不对的,Android项目打Jar应该只包含src里的内容。

一、下面根据反射资源的方式对Android项目进行打Jar包:

1. 首先,在项目中新建一个名为MRsource的类,该类的作用是利用反射根据资源名字获取资源ID。其实,系统也自带了根据资源名字获取资源ID的方法,getResource().getIdentifier("main_activity", "layout", getPackageName()); 第一个参数是资源的名字,第二个参数是资源的类型,如layout, string等,第三个是包名。

MRsource类的内容如下:

package com....;

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) {  
            e.printStackTrace();  
        } catch (SecurityException e) {  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            e.printStackTrace();  
        } catch (NoSuchFieldException e) {  
            e.printStackTrace();  
        }  
  
        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) {  
      e.printStackTrace();  
    } catch (SecurityException e) {  
      e.printStackTrace();  
    } catch (IllegalAccessException e) {  
      e.printStackTrace();  
    } catch (NoSuchFieldException e) {  
      e.printStackTrace();  
    }  
  
    return ids;  
  }  

我的Activity是一个WebViewActivity,进度条可能会不太清晰,可以另外自定义进度条的颜色,刚开始的时候这条语句

Progress progressBar = (ProgressBar) findViewById(MResource.getIdByName(getApplication(), "id", "progressBar"));

是这样写的,progress.setProgress(newProgress);中的progress会报错,原来我在前面已经定义了progress了,所以要把Progress去掉。

具体内容如下:

package com....;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.TextView;

public class WebViewActivity extends Activity {
    private static final String TAG = "WebViewActivity";
    private WebView webView;
    private WebSettings webSettings;
    private ProgressBar progressBar;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    PaSysApplication.getInstance().addActivity(this);   // 将该Activity放入一个栈中,本文请忽略
	    requestWindowFeature(Window.FEATURE_NO_TITLE);
	    if (isNetworkAvailable(this)) {    // 进行联网判断,没网络的话无法进入
	        // setContentView(R.layout.paactivity_webview);
		setContentView(MResource.getIdByName(getApplication(), "layout", "activity_webview"));
		// webView = (WebView) findViewById(R.id.webView);
		webView = (WebView) findViewById(MResource.getIdByName(getApplication(), "id", "webView"));
		// progressBar = (ProgressBar) findViewById(R.id.bar_progress);
		progressBar = (ProgressBar) findViewById(MResource.getIdByName(getApplication(), "id", "bar_progress"));
		webSettings = webView.getSettings();
		webSettings.setJavaScriptEnabled(true);
		AccountManager.getInstance(this).setActivity(this);  // 本文请忽略
		webView.addJavascriptInterface(AccountManager.getInstance(this).getJavascriptObject(), "Obj");  // 添加接口,本文请忽略

                // 添加进度条
		webView.setWebChromeClient(new WebChromeClient() {
		    @Override
		    public void onProgressChanged(WebView view, int newProgress) {
			progressBar.setProgress(newProgress);
			}
		});

		webView.setWebViewClient(new WebViewClient() {
		    @Override
		    public boolean shouldOverrideUrlLoading(WebView view, String url) {
			return false;
			}
		});

		Intent intent = getIntent();
		String url = intent.getStringExtra("url");
		webView.loadUrl(url);
	    } else {
		finish();
	    }

	}

	public boolean isNetworkAvailable(Context context) {
	    ConnectivityManager connectivityManager = (ConnectivityManager) context
	            .getSystemService(Context.CONNECTIVITY_SERVICE);
	    if (connectivityManager == null) {
	        return false;
	    } else {
		NetworkInfo[] networkInfo = connectivityManager.getAllNetworkInfo();
		if (networkInfo != null && networkInfo.length > 0) {
		    for (int i = 0; i < networkInfo.length; i++) {
		        if (networkInfo[i].getState() == NetworkInfo.State.CONNECTED) {
			    return true;
			}
		    }
		}
	    }
	    return false;
	}

}
WebViewActivity对应的layout内容如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <!--
    <ProgressBar
        android:id="@+id/bar_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@color/transparent" />
    --!>
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </WebView>

</LinearLayout>
2. 将该Android项目打成Jar包,注意修改setContentView()和findViewById()的地方,这样反射才会有效。Jar包只包含src。打包过程略,具体请看转载链接。

3. 将Jar包放入测试项目的lib目录下,选中该测试项目,右键打开Properties,选择java Build Path--->Libraries--->Add Jars,选择放入测试项目lib目录下的Jar包,Apply,OK。

使用Eclipse将Android项目打Jar包

4. 将WebViewActivity所需的资源文件放入测试项目对应的文件夹中,我只有一个layout,所以我把我的activity_webview.xml放入测试项目的layout中。

还要记得在AndroidManifest.xml文件中添加所需的权限,Activity声明等内容,注意,Activity需要使用全包名。我需要添加的如下:

<application
        ......
        <activity android:name="com.example.accounttest.WebViewActivity" />
    </application>

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
5. 至此,就可以成功调用Jar包中的layout等其它资源了。



二、除了这个提供Jar包的方法外,还可以使用Library的方法,将我们的WebViewActivity所属的项目当作Library提供给其它人使用,但是这样会暴露我们的源码。

http://developer.android.com/tools/projects/projects-eclipse.html




三、Android Studio提供了aar包,可以将资源文件和src一起打包。