Android开发Android开发经验谈Android技术知识

Android插件化框架—— Atlas

2022-11-23  本文已影响0人  谁动了我的代码

概述

Atlas 是伴随着手机淘宝不断发展而衍生出来的一个运行于 Android 系统上的插件化框架,也可以叫动态组件化框架,主要提供了解耦化、组件化、动态性的支持。是目前比较成熟的方案,功能强大,但相对的,使用和集成的难度也比较大。

Atlas是Hadoop的数据治理和元数据框架。 Atlas是一组可扩展和可扩展的核心基础治理服务,使企业能够有效,高效地满足Hadoop中的合规性要求,并允许与整个企业数据生态系统集成。 Apache Atlas为组织提供了开放的元数据管理和治理功能,以建立其数据资产的目录,对这些资产进行分类和治理,并为数据科学家,分析师和数据治理团队提供围绕这些数据资产的协作功能。

Atlas 的优点:

Atlas 的缺点:

图示

架构原理

Atlas包括以下组件:

效果图

Atlas项目实践

前面我们介绍了Atlas的一些原理性的东西,总的来说,Atlas就是利用远程Bundle的下发方式,为了减少apk的安装体积,Atlas项目使用bundle的加载方式。当用户安装没有Bundle的apk文件时,就从网上下载这个bundle的so,然后加载打开,下载逻辑使用app原生代码编写,加载用按需加载的策略。

Atlas接入

首先新建一个项目,然后新建几个module,如下图。

修改配置

1,把gradle改为3.3

2,然后我们需要为Atlas添加一些配置,引用Atlas插件及依赖仓库,修改工程gradle文件。

//不需要再依赖classpath "com.android.tools.build:gradle"
         classpath "com.taobao.android:atlasplugin:2.3.3.beta2"

3,修改app的build.gradle脚本,需要注意包名的对应关系。

// 需要放最上面初始化
group = "mmc.atlastest"
version = getEnvValue("versionName", "1.0.0");
def apVersion = getEnvValue("apVersion", "");

apply plugin: 'com.android.application'
apply plugin: 'com.taobao.atlas'

android {
   compileSdkVersion 25
   buildToolsVersion "25.0.2"
   defaultConfig {
       applicationId "mmc.atlastest"
       minSdkVersion 15
       targetSdkVersion 25
       versionCode 1
       versionName version
       testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
   }
   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
       }
   }
}

dependencies {
   compile fileTree(include: ['*.jar'], dir: 'libs')
   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:25.3.1'
   testCompile 'junit:junit:4.12'

   //atlas的依赖
   compile('com.taobao.android:atlas_core:5.0.7@aar') {
       transitive = true
   }
   compile 'com.taobao.android:atlasupdate:1.1.4.7@aar'
   compile 'com.alibaba:fastjson:1.1.45.android@jar'

   //项目依赖
   compile project(':librarybundle')
   compile project(':localbundle')
   compile project(':remotebundle')
}

//加入以下配置
atlas {
   atlasEnabled true
   tBuildConfig {
      // autoStartBundles = ['com.android.homebundle'] //自启动bundle配置
       outOfApkBundles = ['remotebundle'] //远程module,列表来的,可填多个
       preLaunch = 'mmc.atlastest.AtlasLaunch' //AppApplication启动之前调用,这个类下面放出代码
   }
   patchConfigs {
       debug {
           createTPatch true
       }
   }
   buildTypes {
       debug {
           if (apVersion) {
               // 打差异补丁 gradlew assembleDebug -DapVersion=1.1.0 -DversionName=1.1.1
               // 对应着本地maven仓库地址 .m2/repository/mmc/atlastest/AP-debug/1.1.4/AP-debug-1.1.4.ap
               baseApDependency "mmc.atlastest:AP-debug:${apVersion}@ap"
               patchConfig patchConfigs.debug
           }
       }
   }
}

String getEnvValue(key, defValue) {
   def val = System.getProperty(key);
   if (null != val) {
       return val;
   }
   val = System.getenv(key);
   if (null != val) {
       return val;
   }
   return defValue;
}

apply plugin: 'maven'
apply plugin: 'maven-publish'

publishing {
   // 指定仓库位置
   repositories {
       mavenLocal()
   }
   publications {
       // 默认本地仓库地址  用户目录/.m2/repository/
       maven(MavenPublication) {
           //读取ap目录上传maven
           artifact "${project.buildDir}/outputs/apk/${project.name}-debug.ap"
           //生成本地maven目录
           groupId group
           artifactId "AP-debug"

4,修改远程bundle和本地bundle的build.gradle脚本

apply plugin: 'com.android.library'
apply plugin: 'com.taobao.atlas'

atlas {
   bundleConfig{
       awbBundle true
   }
   buildTypes {
       debug {
           baseApFile project.rootProject.file('app/build/outputs/apk/app-debug.ap')
       }
   }
}
//只添加上面的配置就行了,下面的是默认生成的

android {
   compileSdkVersion 25
   buildToolsVersion "25.0.2"

   defaultConfig {
       minSdkVersion 15
       targetSdkVersion 25
       versionCode 1
       versionName "1.0"

       testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

   }
   buildTypes {
       release {
           minifyEnabled false
           proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
       }
   }
}

dependencies {
   compile fileTree(include: ['*.jar'], dir: 'libs')
   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:25.3.1'
   testCompile 'junit:junit:4.12'

   //依赖lib中间bundle
   compile project(':librarybundle')
}

5,在宿主app的application中添加如下代码。

public class DemoApplication extends Application

   @Override
   public void onCreate() {
       super.onCreate();

       Atlas.getInstance().setClassNotFoundInterceptorCallback(new ClassNotFoundInterceptorCallback() {
           @Override
           public Intent returnIntent(Intent intent) {
               final String className = intent.getComponent().getClassName();
               final String bundleName = AtlasBundleInfoManager.instance().getBundleForComponet(className);
    
               if (!TextUtils.isEmpty(bundleName) && !AtlasBundleInfoManager.instance().isInternalBundle(bundleName)) {
    
                   //远程bundle
                   Activity activity = ActivityTaskMgr.getInstance().peekTopActivity();
                   File remoteBundleFile = new File(activity.getExternalCacheDir(),"lib" + bundleName.replace(".","_") + ".so");
    
                   String path = "";
                   if (remoteBundleFile.exists()){
                       path = remoteBundleFile.getAbsolutePath();
                   }else {
                       Toast.makeText(activity, " 远程bundle不存在,请确定 : " + remoteBundleFile.getAbsolutePath() , Toast.LENGTH_LONG).show();
                       return intent;
                   }


                   PackageInfo info = activity.getPackageManager().getPackageArchiveInfo(path, 0);
                   try {
                       Atlas.getInstance().installBundle(info.packageName, new File(path));
                   } catch (BundleException e) {
                       Toast.makeText(activity, " 远程bundle 安装失败," + e.getMessage() , Toast.LENGTH_LONG).show();
                       e.printStackTrace();
                   }
    
                   activity.startActivities(new Intent[]{intent});
    
               }
    
               return

6、在app新建一个类AtlasLaunch,继承AtlasPreLauncher。

public class AtlasLaunch implements AtlasPreLauncher
   @Override
   public void initBeforeAtlas(Context context) {

   }
}

项目结构 然后写app的基本功能,示例如下图。

下面是宿主中具体的跳转逻辑实现。

public class MainActivity extends BaseActivity

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

   }

   //打开远程bundle
   public void remote(View view){
       Intent intent = new Intent();
       intent.setClassName(view.getContext(), "mmc.remotebundle.RemoteActivity");
       startActivity(intent);
   }

   //打开本地bundle
   public void local(View view){
       Intent intent = new Intent();
       intent.setClassName(view.getContext(), "mmc.localbundle.LocalActivity");
       startActivity(intent);
   }

   //更新补丁
   public void update(View view){
       new AsyncTask<Void, Void, Void>() {
           @Override
           protected Void doInBackground(Void... voids) {
              update();
               return null;
           }

           @Override
           protected void onPostExecute(Void aVoid) {
               Toast.makeText(MainActivity.this, "更新完成,请重启", Toast.LENGTH_LONG).show();
           }
       }.execute();
   }

   private void update(){
       File updateInfo = new File(getExternalCacheDir(), "update.json");
       if (!updateInfo.exists()) {
           showToast("更新信息不存在,请先 执行 buildTpatch.sh");
           return;
       }

       String jsonStr = new String(FileUtils.readFile(updateInfo));
       UpdateInfo info = JSON.parseObject(jsonStr, UpdateInfo.class);
    
       File patchFile = new File(getExternalCacheDir(), "patch-" + info.updateVersion + "@" + info.baseVersion + ".tpatch");
       try {
           AtlasUpdater.update(info, patchFile);
       } catch (Throwable e) {
           e.printStackTrace();
           showToast("更新失败, "

安装运行项目,就可以看到如下图所示的效果。

此时还有以下工具需要完成:

1,这个时候点击远程bundle会弹出说没有so文件,因为还没打so包呢

2、点击本地bundle,是可以跳转到那个本地bundle页面

3、点击更新补丁,会提示更新信息不存在

打远程bundle的so文件 下面要打包出远程bundle的so文件,补丁的差异包和更新说明。

1,打so文件,每个远程都会生成一个so文件的。打开AS的Terminal,输入:gradlew clean assembleDebug publish,然后回车,如下图:

正常的话,会提示下面的正确信息。

成功的话,app的build文件夹里,会生成这个so文件,这个就是远程bundle的so文件,把这个文件放到手机内存卡Android/data/mmc.atlastest/cache 文件夹里面,然后再打开app,点击“远程Bundle”,这个时候就能跳转过去了。


更新补丁,打差异包和更新说明 接着第一步,然后修改版本号,对本地Bundle进行文字修改,对app主项目也可以修改。

修改后,在Terminal里面输入:gradlew clean assembleDebug -DapVersinotallow=1.0.0 -Dversinotallow=1.0.1

回车,成功后会生成补丁差异包和更新说明,如下图:

把红色圈中的两个文件,放到手机内存卡Android/data/mmc.atlastest/cache 文件夹里面,然后点击“更新补丁”,过一会,提示更新成功后,就退出杀死app,再打开就是后面修改的内容了。

以上就是Android插件化中的Atlas原理以及实战浅析,如果想更深入学习Android插件化或者进阶核心技术,可以参考《Android核心技术手册》文档,里面技术归纳了几十个知识点。更加前面方便学习,点击查看获取方法。

Atlas使用步骤总结

1、配置好,安装1.0.0的app

2、用命令“gradlew clean assembleDebug publish”打AP,得到远程Bundle的so文件

3、修改版本号,修改版本内容

4、用命令“gradlew clean assembleDebug -DapVersion=1.0.0 -DversionName=1.0.1”打差异包补丁和更新说明

5、把上面得到的三个文件放到app的cache目录里面

6、运行更新方法,杀死app,重启

上一篇下一篇

猜你喜欢

热点阅读