前置:由于端内直连Jira提bug需要一个SDK,所以探索了下aar与jar的区别。
Android中常见的第三方库包括:*.so、*.jar、*.aar,一般来说.so是C或C++语言的内容打包成的库,由于本项目是java语言,所以此处不探究so。
一、jar
1、说明
只包含了class文件与清单文件 ,不包含资源文件,如图片等所有res中的文件。
JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩文件。
Jar的优点:安全性、减少下载时间、传输平台扩展、包密封、包版本控制、可移植性。
打jar包时,项目里的res文件是用不了的,若想用图片文件,可以将图片文件放进assets文件里面打进jar包再进行调用,但必须注意jar里面assets文件夹里面的文件不能和调用项目里面assets文件夹里面的文件重名。
2、打jar包方法:
网上方法很多也很详细,不再赘述,给个链接:http://blog.csdn.net/u013895206/article/details/52692415
3、使用jar方式:
*.jar:拷贝到:libs目录,eclipse直接导入即可,AndroidStudio项目中添加:
dependencies {
compile fileTree(include: ['*.jar'], dir:'libs')
}
重新编译一次项目既可完成加载。
二、aar
1、说明
Android库项目的二进制归档文件,包含所有资源,class以及res资源文件全部包含。
将aar解压(后缀改为.zip,再解压文件)打开后,可以看到每个aar解压后的内容可能不完全一样,但是都会包含AndroidManifest.xml,classes.jar,res,R.txt。
2、打aar包方法:
先把想要打包成sdk的项目做成Android libraries B,不要建成Android project ;
然后建立一个新的Android project A 去调用写好的libraries B;
运行后,studio就自动把我们的librarys B自动打包成aar包了,这就是我们想要的sdk了(路径:module 下,build/outputs/aar/)
如果运行后,没在目录下看到 aar,可以按照下图方式执行,执行成功后,就可以在左侧的:build/outputs/aar/ 下看到对应的 aar 文件了:
3、Android Studio使用aar方式:
第一步:拷贝到:libs目录
第二步:build.gradle 配置文件中更改为
repositories {
flatDir {
dirs'libs'
}
}
dependencies {
compile(name:'genius', ext:'aar')
}
三、总结
1、如何选择?
如果你只是一个简单的类库那么使用生成的*.jar文件即可;如果你的是一个UI库,包含一些自己写的控件布局文件以及字体等资源文件那么就只能使用*.aar文件。
2、因为端内直连Jira提bug,包含UI内容,且只是供Android使用的,同时Android Studio已经被广泛使用(Eclipse使用aar较麻烦,教程:https://www.cnblogs.com/shortboy/p/4424944.html),所以我最终选择了使用.aar作为咱们最后的SDK。
今天咱们看看android studio的jar打包,但是jar包里面呢res文件是用不了的,那想用图片文件怎么办呢,这里可以把图片文件放进assets文件里面打进jar包调用还是可以得,但是有点小小的瑕疵就是jar里面assets文件夹里面的文件不能跟调用项目里面assets文件夹里面的文件重名。
好了,接下来看看到底该如何弄呢?首先第一步肯定是需要创建一个项目,这里就不演示了。
第二步:咱们需要在项目里面新new出一个module,请看图:
第三步:new了module之后呢就需要创建咱们需要调用的jar里面的代码和gradle导包需要的一些代码,这里呢我们写的代码有部分是需要调用资源图片的,所以我们这里在src\main路径里面创建一个assets文件夹,并给里面一张图片。当然了,我们打出的jar给别人用肯定是要安全点,这里呢需要加上混淆的代码了。帖完图之后我会把几个需要的代码给粘贴出来供大家参考。请看图:
这里是java代码,我这里呢就写了一个log打印,toast提示,和一个调用assets文件图片的代码。请看代码:
package com.wyw.mylibrary;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.InputStream;
/**
* Created by wyw on 2016/9/27.
*/
public class Logs {
public static void error() {
LogUtli.e();
}
public static Bitmap getAssets(Context context) {
Bitmap bitmap = null;
try {
InputStream resourceAsStream = context.getClass().getClassLoader().getResourceAsStream("assets/" + "aabb");
bitmap = BitmapFactory.decodeStream(resourceAsStream);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
package com.wyw.mylibrary;
import android.util.Log;
/**
* Created by wyw on 2016/9/27.
*/
public class LogUtli {
public static void e() {
Log.e("123456", "eeeeeeeee");
}
public static void v() {
Log.v("123456", "vvvvvvvv");
}
public void i() {
Log.i("123456", "iiiiiiiii");
}
private void d() {
Log.d("123456", "ddddddddd");
}
}
package com.wyw.mylibrary;
import android.content.Context;
import android.widget.Toast;
/**
* Created by wyw on 2016/9/27.
*/
public class ToastUtil {
public static void show(Context context, String txt) {
adshow(context, txt);
}
private static void adshow(Context context, String txt) {
Toast.makeText(context, txt, Toast.LENGTH_LONG).show();
}
}
接下来就是module里面的build.gradle代码,最主要的一段就是上面截图那部分。请看代码:
apply plugin: 'com.android.library'
android {
compileSdkVersion 24
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 19
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
}
//打jar包
def SDK_BASENAME = "wywSdk_V1.0";
def sdkJarPath = "build";
def zipFile = file('build/intermediates/bundles/release/classes.jar')
task makeJar(type: Jar) {
from zipTree(zipFile)
from fileTree(dir: 'src/main', includes: ['assets/**'])
baseName = SDK_BASENAME
destinationDir = file(sdkJarPath)
}
makeJar.dependsOn(build)
//在终端执行生成JAR包
// gradlew makeJar
因为我们用了混淆,所以android studio 默认混淆文件proguard-rules.pro里面肯定要写一部分混淆的逻辑的,因为外部调用的代码是不能混淆的,不然外面调用的变成了a类a方法了。所以这里外面调用的是ToastUtil和Logs类,所以这2个类不能混淆,而LogUtli我们就不管了让他混淆。请看图和代码:
-optimizationpasses 5 # 指定代码的迭代优化次数
-dontusemixedcaseclassnames # 不使用大小写名称的类名
-dontskipnonpubliclibraryclasses # 指定不去忽略非公共的库类
-dontpreverify # 混淆时是否做预校验
-verbose # 混淆时是否记录日志
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 优化选项
-keep public class com.wyw.mylibrary.ToastUtil{
public protected *;
}
-keep public class com.wyw.mylibrary.Logs{
public protected *;
}
第四步:现在咱们一切就绪了,就差打包了。好了,我们现在需要在android studio 最下面那排里面有个终端“Terminal”点击它。到终端后路径先指定到你项目的目录,然后输入gradlew makeJar这个命令。由于有的人可能打开终端的时候目录不是项目目录,你这里就需要自己手动指定到你的项目目录,至于怎么弄去百度吧,这个很多的。接下来就是按回车了,如果你是第一次用,它会先去下载文件大概几分钟吧,下完之后再运行次就可以了。请看图:
运行完之后呢,在module项目里面build文件夹下面有个jar包,这就是我们要的jar包,现在就可以把它拷贝到我们的主项目里面去了,请看图:
这里说一句就是如果改了module代码需要重新打jar包,我建议先删除build里面的部分文件,图中带红框的都需要删除,重新生成会省很多事。请看图:
第五步:把jar拷贝进了主项目,现在我们需要写一下依赖,在主项目项目的build.gradle文件里面添加这段代码compile files(‘libs/wywSdk_V1.0.jar’),添加完之后再按右上角sync Now,重新build一下。请看图:
第六步:jar和依赖都弄好了,现在我们就需要去调用了。请看图和代码:
package com.wyw.myapplication;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;
import com.wyw.mylibrary.Logs;
import com.wyw.mylibrary.ToastUtil;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Bitmap assets = Logs.getAssets(MainActivity.this);
if (assets != null) {
imageView.setImageBitmap(assets);
}
Logs.error();
ToastUtil.show(MainActivity.this, "哈哈哈哈哈哈哈");
}
}
运行验证下,看下图我们明白了jar打好了,并且assets文件夹里面的图片也调用到了。请看图:
如果细心的看下会发现我们的jar包里面的a类里面的方法就只有一个了。原本混淆类的方法是有4个的,为什么会变的只有一个了呢,这个就是混淆的规则了就是混淆的代码只有调用的部分才会打包进去,而没有混淆的代码是全部打包进去。请看图的对比(灰色的方法是没有被调用):