在Android开发的时候,有时候我们需要封装自定义组件,并且希望将封装好的自定义组件到处为一个lib库,实现给其他程序使用的效果,而传统的Jar包并不能很好的实现这个需求,因为传统的Jar包不能很好的支持res中的各个xml和R文件,这时我们就需要打包成aar库来使用。
首先我们需要生成一个AAR的库,这里以一个简单的自定义组件为例,来生成AAR库.
首先创建一个Model
这里要注意选择AndroidLib
我们的自定义组件就要在myview这个Model下进行编写
首先我们简单编写一个自定义组件,并且要使用自定义的属性,目标是在ImageView的基础上增加文字显示的功能,首先是自定义属性,在myview/values 下创建attrs.xml文件,编写自定义组件所需要的属性:
<resources>
<declare-styleable name="MyView">
<attr name="text" format="string"/>
declare-styleable>
resources>
然后编写Java代码,就是简单的在ImageView的基础上增加绘制文字的功能:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.widget.ImageView;
public class MyView extends ImageView {
private String text;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
}
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyView);
text = ta.getString(R.styleable.MyView_text);
ta.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (text != null) {
TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(40);
canvas.drawText(text, getMeasuredWidth() / 2, getMeasuredHeight() - 10, paint);
}
}
}
到这里,基本上代码的部分就完成了,最后我们需要检查一下,lib的AndroidManifest.xml和build.gradle,将用不到的功能和依赖全部删除,因为最后我们的库是要用在其他项目上的,为了避免AndroidManifest.xml合并失败或者依赖冲突,我们需要保证我们的lib使用的是最小依赖.
AndroidManifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cfy.com.myview" />
可以看到AndroidManifest中几乎是什么也没有的,然后是build.gradle:
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
可以看到也没有任何的dependencies依赖,实际上我们也应该将minSdk设置为 可以保证正常运行的最小版本
.
对于AndroidStudio来说,只要其一编译就会声场AAR文件,我们可以使用gradle来手动编译它,使用gradle的任务就可以编译生成AAR了
生成的路径在model下的out文件中,通常我们使用release版本的即可
因为AndroidStudio都是使用的Gradle进行编译的,所以使用AAR文件非常简单
首先将AAR文件放到项目的lib文件夹中:
然后修改build.gradle文件,让libs文件夹中的所有aar文件均可以被添加依赖:
只要将*.aar添加到include的列表中即可
接下来测试一下:
只需要修改布局文件,将我们的自定义组件添加上就行:
<FrameLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<cfy.com.myview.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
app:text="Hello"/>
FrameLayout>
可以看到我们的自定义组件已经能正确的被使用了
如果我们的开发环境并不是一个单纯的AndroidApp的话,需要在源码的环境中依赖AAR文件的话,我们就需要编写android.mk文件来添加AAR文件的依赖了,首先我们在源码路径下创建一个项目,目录结构如下:
arr文件就放在libs文件下就好了,主要是Android.mk文件的编写:
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
LOCAL_MIN_SDK_VERSION := 23
LOCAL_PACKAGE_NAME := AARDemo
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
LOCAL_DEX_PREOPT := false
LOCAL_STATIC_JAVA_AAR_LIBRARIES := myview
include $(BUILD_PACKAGE)
LOCAL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml
LOCAL_AAPT_FLAGS := \
--auto-add-overlay \
--extra-packages cfy.com.myview
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := myview:libs/myview-release.aar
include $(BUILD_MULTI_PREBUILT)
使用AAR文件的时候和引入jar很像,首先是在编译时使用 LOCAL_STATIC_JAVA_AAR_LIBRARIES := myview
来指定依赖的AAR文件,接下来就是定义AAR文件了
LOCAL_MANIFEST_FILE := $(LOCAL_PATH)/AndroidManifest.xml
的作用是指定AndroidManifest,因为AAR是一个Android的Lib,所以可能会有Activit,Service等的封装,会在AAR自己的AndroidManifest.xml中进行注册,那么就需要合并AndroidManifest,所以需要指定一下
LOCAL_AAPT_FLAGS
是将AAR的资源文件进行合并 否则即使编译过了,在运行时也会crash的,主要是AAR的包名不要填写错了
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := myview:libs/myview-release.aar
则是指定AAR文件的位置,注意的是myview是给这个AAR依赖起一个名字,需要和上面的LOCAL_STATIC_JAVA_AAR_LIBRARIES := myview
对应上
而最后我们是要编译AAR所以需要加上include $(BUILD_MULTI_PREBUILT)
编译完成后,安装运行,就会看见我们封装的自定义组件被正确的加载了
由于我没有添加appcompat的依赖,所以主题与AS项目略有不同,这个无关本篇博客的注意,忽略就好了~