AndroidX升级总结

2022-04-12  本文已影响0人  清明捉鬼

前言

随着2021年即将结束,因技术迭代的升级,不少公司开始使用AndroidX代替原有的各种support包,升级势在必行

AndroidX升级

5.maven打包配置,在gradle.properties配置权限账号,POM_NAMEPOM_VERSION;据悉以-SNAPSHOT为后缀名的可无限覆盖打包否则需将版本号增加,具体详情咨询项目组
6.向git仓库提交组件代码,确保组件与主工程代码同时无问题后可提交代码,此时可能会遇到git的问题,可查看下文【本次升级所遇问题】

x64升级

x64升级主要涉及cpu abi这块知识,关于这块知识可以百度搜索查看一番,本次升级主要对原有32位的内容进行适配,涉及C及C++代码编译,本次采用cmake方式进行编译打出so包

  1. AS中新建C++模板的工程应用


    image.png
  2. 将需要编译源码文件复制进工程中
    调用的jni方法在头文件中已有声明,相关代码亦无需改写,打出的包名前缀“lib”关键字不可删除,否则在System.loadLirary()方法中会报错,本次按如下配置直接编译打包即可

  3. 在Module的build文件defaultConfig{}方法中添加ndk配置

android {
        ...
        ndk {
            abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64','armeabi','mips','mips64'
        }
    }

abiFilters主要配置so包目标架构版本,当前主流cpu架构如配置所列,本次目标配置为打出64位包故只配置arm64-v8a,需提醒apk包瘦身一般大头就是so包,故兼容与体积
需斟酌

  1. CmakeLists分别配置打包
    CMakeLists.txt文件中分别配置如下代码,当前打包方式是配置一次打一个so包,故若打多个so包需配置多次,打的包有两种一种是debug包,可输出调试日志,一种是release包较为安全,release的so包直接对工程进行签名打包即可得到,编译过程中最好清除.cxx文件夹与build文件夹否则可能输出错误,本次目标打出两份源码的.so包文件,故其CmakeLists配置分别如下:
//OfflineXXXCode.so包配置
cmake_minimum_required(VERSION 3.4.1)

add_library(
        cnXXXCode
        SHARED
        cnXXXCode.cpp
        com_xxx_mobile_apa_staffcode_jni_OfflineXXXCodeJNI.cpp
        )
find_library(log-lib log)

target_link_libraries(cnXXXCode android ${log-lib})

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -s")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -s")
//scancode_encode_GeneratorCode .so包配置
cmake_minimum_required(VERSION 3.4.1)

add_library(
        XXXCode
        SHARED
        aes.c
        encryption.c
        com_xxx_mobile_apa_scancode_encode_GeneratorCode.c
        )
# 头文件目录
include_directories( ${PROJECT_SOURCE_DIR})

find_library(log-lib log)

target_link_libraries(XXXCode android ${log-lib})

set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")

set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -s")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -s")

本次升级所遇问题

2021-12-21 19:35:13.223 19798-19798/com.xxx.mobile.apa I/ning.mobile.ep: The ClassLoaderContext is a special shared library.
2021-12-21 19:35:16.105 19798-19798/com.xxx.mobile.apa I/Perf: Connecting to perf service.
12-27 14:43:02.250 30049 30049 E AndroidRuntime: FATAL EXCEPTION: main
12-27 14:43:02.250 30049 30049 E AndroidRuntime: Process: com.xxx.mobile.apa, PID: 30049
12-27 14:43:02.250 30049 30049 E AndroidRuntime: java.lang.NoSuchMethodError: No virtual method placeholder(I)Lcom/bumptech/glide/request/RequestOptions; in class Lcom/bumptech/glide/request/RequestOptions; or its super classes (declaration of 'com.bumptech.glide.request.RequestOptions' appears in /data/app/com.xxx.mobile.apa-gzUOAXBojHInZ80NNkkQTQ==/base.apk!classes2.dex)
12-27 14:43:02.250 30049 30049 E AndroidRuntime:    at com.xxx.mobile.apa.creditcard.utils.GlideUtils.loadImage(GlideUtils.java:35)

报错如上,在升级过程中遇到glide4.3.0版本与X兼容问题,网上有很多blog说4.9版本即有AndroidX经本人查看自4.10版本才开始有,4.9是没有的,本次为与融合项目一致采用版本为4.11.0

无效可尝试使用命令git branch --set-upstream-to [分支名]再无效则分别用AS打开对应组件工程直接提交

3种处理方式:
1.反射处理设置方向
a、封装方法1
b、封装方法2:

/**
* 在oncrate()里super()之前调用
* Only fullscreen opaque activities can request orientation
*/
protected void fitTranslucent(){
if (getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.O
&&Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
changeTranslucentOrient();
}
}
private void changeTranslucentOrient(){
try {
Field field = Activity.class.getDeclaredField("mActivityInfo");
field.setAccessible(true);
ActivityInfo activityInfo = (ActivityInfo)field.get(this);
activityInfo.screenOrientation = -1;
field.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
} 

2.在onCreate()里super()与setContentView()之间重设非透明主题

//setContentView之前调用
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.O)){
  setTheme(R.style.xxxx)
}

3.设置targetSdkVersion 26,本次升级采用此法,因本次组件与主工程有很多Activity未继承自定义的基类Activity又组件与主工程未将公共基础部分抽取成单独组件,改动量太大,故采取降低版本的方法,节约时间

Crash

glide版本兼容发生崩溃
jni方法调用未找到方法崩溃
xml引用已剔除组件控件崩溃
8.0手机透明Activity与方向设置冲突导致的崩溃

记录整理

错误转换 正确转换
android.support.annotation. androidx.annotation.
androidx.appcompat.widget. androidx.recyclerview.widget.
android.support.v7.widget. androidx.recyclerview.widget.
androidx.core.view.ViewPager androidx.viewpager.widget.ViewPager
androidx.core.view.PagerAdapter androidx.viewpager.widget.PagerAdapter
androidx.core.app.FragmentManager androidx.fragment.app.FragmentManager
androidx.core.app.Fragment androidx.fragment.app.Fragment
androidx.core.app.DialogFragment androidx.fragment.app.DialogFragment
androidx.core.app.FragmentActivity androidx.fragment.app.FragmentActivity
androidx.core.app.FragmentTransaction androidx.fragment.app.FragmentTransaction
androidx.core.content.LocalBroadcastManager androidx.localbroadcastmanager.content.LocalBroadcastManager
android.arch.core
android.arch.lifecycle
android.arch.paging
android.arch.persistence
import os

DEBUG=True
allSearchKeywords=[]
#根据文件扩展名判断文件类型
def endWith(s,*endstring):
    array = map(s.endswith,endstring)
    if True in array:
        return True
    else:
        return False

#将全部已搜索到的关键字列表中的内容保存到result.log文件中
def writeResultLog(allExistsKeywords):
    #行分隔符
    ls = os.linesep
    #结果日志文件名
    logfilename = "C:\\Users\\dell\\Desktop\\AndroidX_Improve_Version\\result.log" #相对路径,文件在.py文件所在的目录中
    try:
        fobj = open(logfilename,'w')
    except IOError as e:
        print("*** file open error:",e)
    else:
        fobj.writelines(['%s%s' % (keyword,ls) for keyword in allExistsKeywords])
        fobj.close()    
 
#搜索指定关键字是否在指定的文件中存在
def searchFilesContent(dirname):
      for keyword in allSearchKeywords:
            print("***keyword",keyword)
      allExistsKeywords=[]

      for (root,dirs,files) in os.walk(dirname):
            for file in files:
                  #只在扩展名为.java/.xml文件中搜索
                  if endWith(file,'.java','.xml'):
                        #打开文件
                        filename = root + os.sep + file
                        filename = filename.replace("\\","\\\\") #将路径中的单反斜杠替换为双反斜杠,因为单反斜杠可能会导致将路径中的内容进行转义了,replace函数中"\\"表示单反斜杠,"\\\\"表示双反斜杠
                        try:
                              fobj = open(filename,'r', encoding='utf-8');
                              print("***search",filename)
                        except IOError as e:
                              print("*** file open error:",e)
                        else:
                              #遍历文件的每一行
                              for fileLine in fobj:
                                    #判断当前行是否包含所有搜索关键字
                                    for keyword in allSearchKeywords:
                                          if keyword in fileLine: 
                                                print("***hit",filename)
                                                allExistsKeywords.append("***hit "+keyword+" path: "+filename)
                        fobj.close()
      #全部文件遍历结束
      writeResultLog(allExistsKeywords)
      print ("OVER!")

#仅当本python模块直接执行时,才执行如下语句,若被别的python模块引入,则不执行
if __name__ == '__main__':
      allSearchKeywords=["androidx.appcompat.widget.RecyclerView","androidx.core.app.Fragment","androidx.core.app.FragmentActivity","android.support.v4"
      ,"androidx.core.view.ViewPager","android.arch.core","android.arch.lifecycle","android.arch.paging","android.arch.persistence"]

      #搜索的project路径
      searchFilesContent(r"G:\CNJRWorkSpace")
      # searchFilesContent(r"D:\dev\mainProject\CNMain_android")
      #searchFilesContent(r"D:\dev\mainProject\CNFCommonKits_android\src\main\res\layout")
上一篇 下一篇

猜你喜欢

热点阅读