美文网首页
Android aar攻略-完整项目打包aar引用到新项目中引用

Android aar攻略-完整项目打包aar引用到新项目中引用

作者: Leon_w | 来源:发表于2018-09-30 13:19 被阅读0次

一 . 背景

公司一直在做一个的项目,需要上架,因为某种原因上不上去.结果出了一个主意想把以前已死的项目作为马甲包,帮助新项目上架.这个任务给我了.我一时间想到的解决方案就是把老项目打包成aar包,放到新项目里.其中遇见了很多的坑,在此做一下记录.


一 .完整项目打包aar 的流程

aar包简单介绍

aar包含所有资源,class,xml布局文件以及res资源文件全部包含。但是他不含有你在项目里引用的三方库.
捎带解释下jar.jar只包含了class文件与清单文件,不包含资源文件,如图片等所有res中的文件。所以如果想打包整个工程到新项目里用aar还是比较方便的.


第一步 修改build.gradle(app)

首先先将项目中的apply plugin: 'com.android.application' 替换成apply plugin: 'com.android.library'.如下

//apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
android {
    packagingOptions {
        exclude 'META-INF/maven/com.belerweb/pinyin4j/pom.xml'
        exclude 'META-INF/maven/com.belerweb/pinyin4j/pom.properties'
    }
    dexOptions {
        //incremental true
        javaMaxHeapSize "4g"
    }
    signingConfigs {
        config {
            storeFile file('/home/conf/com.cloudcns.debug.keystore')
        }
    }

第二步 修改manifests

将application里面的一些里的name,icon,label,theme等删掉 如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.saileikeji.sych">

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT"/>

    <uses-feature android:name="android.hardware.camera"/>
    <uses-feature android:name="android.hardware.camera.autofocus"/>

    <uses-permission android:name="android.permission.VIBRATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    
    <application
        <!--android:name=".application.MyApplication"-->
        <!--android:allowBackup="true"-->
        <!--android:icon="@mipmap/ic_launcher"-->
        <!--android:label="@string/app_name"-->
        <!--android:roundIcon="@mipmap/ic_launcher_round"-->
        <!--android:supportsRtl="true"-->
        <!--android:theme="@style/AppTheme"-->
           android:allowBackup="true"
           android:supportsRtl="true">

然后再将manifests中的 主启动的intent-filter 删掉,如下:

        <activity
            android:name=".activity.SplashActivity"
            android:screenOrientation="portrait"
            android:theme="@style/AppWelcome">
            <!--<intent-filter>-->
                <!--<action android:name="android.intent.action.MAIN"/>-->
                <!--<category android:name="android.intent.category.LAUNCHER"/>-->
            <!--</intent-filter>-->
        </activity>

如果项目中有加meta-data 也可以将meta-data 删掉 在你要引入的项目里重新加上.我这里直接注释掉了如下:

        <!--<meta-data-->
            <!--android:name="UMENG_APPKEY"-->
            <!--android:value="596d9dbcf5ade420c8000e27" />-->
        <!--<meta-data-->
            <!--android:name="UMENG_MESSAGE_SECRET"-->
            <!--android:value="7e05110fc72e6803e8adcf08f199b0d7" />-->
        <!--<meta-data-->
            <!--android:name="UMENG_CHANNEL"-->
            <!--android:value="YingYongBao" />-->

第三步 如果你的项目里使用了butterknife,出现问题不要害怕

这个butterknife当时坑的我很惨,花了很长时间才解决掉.具体步骤如下:
之前测试了很多个butterknife 版本,只发现用8.4.0 好使.话不能说那么肯定.大家也可以用别的试试.首先在
buid.gradle(Project) 中增加
classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'.如下


image.png

其次在buid.gradle(app)中增加
apply plugin: 'com.jakewharton.butterknife'

image.png

在下面dependencies 中增加:

    compile 'com.jakewharton:butterknife:8.4.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'

之后,将项目里的R改成R2 因为R在library中报错.如下:

public class MainActivity extends BaseFragmentActivity implements MainHandler.UICallback, BaseHandler.UiCallback, View.OnClickListener, OtherHandler.PayCallback, OtherHandler.CommentCallback, NavigationView.OnNavigationItemSelectedListener {
    @BindView(R2.id.main_pager)
    NoSlidingViewPaper mainPager;
    @BindView(R2.id.tab1)
    LinearLayout tab1;
    @BindView(R2.id.tab2)
    RelativeLayout tab2;
    @BindView(R2.id.tab3)
    RelativeLayout tab3;
    @BindView(R2.id.tab4)
    LinearLayout tab4;
    @BindView(R2.id.tv_new_people)
    TextView tvNewPeople;
    @BindView(R2.id.nav_view)
    NavigationView navView;
    @BindView(R2.id.drawer_layout)
    DrawerLayout drawerLayout;
    @BindView(R2.id.iv_1)
    ImageView iv1;
    @BindView(R2.id.ll_bottom)
    LinearLayout llBottom;
    @BindView(R2.id.main_back)
    RelativeLayout mainBack;
    @BindView(R2.id.imageView1)
    ImageView imageView1;
    @BindView(R2.id.imageView2)
    ImageView imageView2;
    @BindView(R2.id.load_image)
    LinearLayout loadImage;

在就是很重要的

@OnClick({R2.id.textView, R2.id.button1, R2.id.button2, R2.id.button3, R2.id.image})
public void onViewClicked(View view) {

 int i = view.getId();
  if (i == R.id.textView) {
    
  } else if (i == R.id.button1) {
    
  } else if (i == R.id.button2) {
    
  } else if (i == R.id.button3) {
    
  } else if (i == R.id.tv) {
    
  }

}

library中的 不可以使用switch case,必须要用if else来的代替,否则空指针等其他错误。这里switch case 转 if else 教给大家一个简单的快捷键 Ait+Enter 对准switch 可以转换..我的项目里我是将所有 onViewClicked里的switch case 转成 if else了
上面的OnClick 里必须为R2 不然回报错.再就是下面的R 必须为R 不然你项目里的所有点击事件会不好使.这里非常重要.我在这里困了一天多


第四步 Assert资源获取

内嵌在其他应用中,原本APK中的Assert目录内的资源可能找不到。解决方法是,可以将Assert目录内的资源打包成一个ZIP文件放在 /RAW目录下。在项目初始化的时候,解压到指定目录下。使用的时候在AssertManager中使用绝对路径获取资源在于前端页面交互上,JS相关代码及资源一般也存放在Assert目录下,在webview.load()时,可以通过 file:/ 绝对路径 ,来加载PS:Assert 目录与 /raw 目录的区别:访问方式,目录结构,大小写,压缩方式等。


第五步 Application参数的传递问题

每一个Android App都有一个application context,这个参数需要工程传递给我们,调试的时候可以在壳工程的Manifest.xml中指定默认的Application.并在默认的Application中初始化aar.如下:

public class MyApplication extends MultiDexApplication implements CrashProcessHandler.ICoprocessor {

    public static AssetsDatabaseManager mg;
    public static boolean isKFSDK;
    public static Application app;
    public static Handler handler;

    @Override
    public void onCreate() {
        super.onCreate();
        handler = new Handler(){

        };
        app = this;

    }

    public static Context setInstance(Application appa){
        app=appa;
        return app;
    }
    public static Context getInstance() {
        return app;
    }

MyApplication .setInstance 是在你主工程的Application 里写的


第六步 打成aar

双击右侧的assembleRelease,如下图位置


image.png

成功后会在这里看到.如下:

image.png

然后就可以将app-release.aar 导入新工程里了!

到此为止完整项目打包aar算是完成了


二 .将aar 引到工程里

1.把aar文件放在一个文件目录内,比如就放在libs目录内 如下:

image.png

想要生成jniLibs 可以添加下面代码在build.gradle(app) android中:

sourceSets{
        main{
            jniLibs.srcDirs=['libs']
        }
    }

2.build.gradle(app)里添加如下内容:

    repositories {
        flatDir {
            dirs 'libs'
        }
    }

这样可以找到路径


3.dependencies 添加引用:

implementation (name: 'app-release',ext: 'aar')

aar 里面引用的三方库 在主项目上引用.比如:

  implementation 'ca.barrenechea.header-decor:header-decor:0.2.6'
    implementation 'com.timehop.stickyheadersrecyclerview:library:0.4.3@aar'
//    implementation 'com.google.zxing:core:3.2.1'
    implementation 'com.google.android.gms:play-services-gcm:9.4.0'
    implementation 'com.umeng.analytics:analytics:latest.integration'
    implementation 'com.jcodecraeer:xrecyclerview:1.3.2'
    implementation 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
    implementation 'com.android.support:cardview-v7:23.4.0'
    implementation('com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30') {
        exclude group: 'com.android.support'
    }

发现重复的可以以这样的方式移除掉:

    implementation('com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30') {
        exclude group: 'com.android.support'
    }

4.主项目的butterknife 需要跟aar 里面使用一样的版本.配置跟上面butterknife 一样.我就不重复写了.


5.manifests 设置

将原aar 项目里的activity ,service 等写在现在的manifests.不写的话会找不到activity/service .写的时候一定要带着包名,如下 :

      <service
            android:name="包名.service.QianguanService"
            android:enabled="true"
            android:exported="true" />
     <activity
            android:name="包名.ui.EaseBaiduMapActivity"
            android:screenOrientation="portrait"
            android:theme="@style/horizontal_slide" />

meta-data 等也在manifests 写上:

        <meta-data
        android:name="EASEMOB_APPKEY"
        android:value="xxxxxxxx" />

6.Application 上的设置

1.在Application 上将原Application 里的三方sdk 设置参数.写在主项目的Application中.
2.在Application上初始化aar包里的application.如下:

image.png

这样在项目里就可以使用aar包里的东西了.


7.主工程调aar 里的activity:

如下:

  @OnClick({R.id.btn_login, R.id.btn_tourist_preview})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_login:
                Intent in=new Intent();
                in.setClassName(this,"包名.activity.StartActivity");
                startActivity(in);
//                start(LoginActivity.class);
                finish();
                break;
            case R.id.btn_tourist_preview:
                start(MainActivity.class);
                finish();
                break;
        }
    }

这样完整的项目打包成aar 引用到新项目里就完成了.

相关文章

网友评论

      本文标题:Android aar攻略-完整项目打包aar引用到新项目中引用

      本文链接:https://www.haomeiwen.com/subject/jjnioftx.html