Android使用aar封装自定义组件

在Android开发的时候,有时候我们需要封装自定义组件,并且希望将封装好的自定义组件到处为一个lib库,实现给其他程序使用的效果,而传统的Jar包并不能很好的实现这个需求,因为传统的Jar包不能很好的支持res中的各个xml和R文件,这时我们就需要打包成aar库来使用。

生成AAR库

首先我们需要生成一个AAR的库,这里以一个简单的自定义组件为例,来生成AAR库.

创建AndroidLib

首先创建一个Model

Android使用aar封装自定义组件_第1张图片

这里要注意选择AndroidLib

Android使用aar封装自定义组件_第2张图片

创建好Model之后,目录结构如下:
Android使用aar封装自定义组件_第3张图片

我们的自定义组件就要在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:

Android使用aar封装自定义组件_第4张图片

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设置为 可以保证正常运行的最小版本.

编译生成AAR

对于AndroidStudio来说,只要其一编译就会声场AAR文件,我们可以使用gradle来手动编译它,使用gradle的任务就可以编译生成AAR了

Android使用aar封装自定义组件_第5张图片

生成的路径在model下的out文件中,通常我们使用release版本的即可

Android使用aar封装自定义组件_第6张图片

AAR 的使用

在AndroidStudio下使用

因为AndroidStudio都是使用的Gradle进行编译的,所以使用AAR文件非常简单

首先将AAR文件放到项目的lib文件夹中:

Android使用aar封装自定义组件_第7张图片

然后修改build.gradle文件,让libs文件夹中的所有aar文件均可以被添加依赖:

Android使用aar封装自定义组件_第8张图片

只要将*.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>

Android使用aar封装自定义组件_第9张图片

可以看到我们的自定义组件已经能正确的被使用了

Android源码使用aar

如果我们的开发环境并不是一个单纯的AndroidApp的话,需要在源码的环境中依赖AAR文件的话,我们就需要编写android.mk文件来添加AAR文件的依赖了,首先我们在源码路径下创建一个项目,目录结构如下:

Android使用aar封装自定义组件_第10张图片

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)

编译完成后,安装运行,就会看见我们封装的自定义组件被正确的加载了

Android使用aar封装自定义组件_第11张图片

由于我没有添加appcompat的依赖,所以主题与AS项目略有不同,这个无关本篇博客的注意,忽略就好了~

你可能感兴趣的:(AOSP,Android人生)