Android兼容性系统app开发的一些探究

说明

本文是我根据自己开发期间项目需求探究的总结,里面有一些问题和说明的情况,可能不全面或者不准确,还请读者包含指正,但是此文对此标题的相关开发有较大参考价值,对节省开发和探究时间有较大帮助。

起因

项目开发期间,遇到过一个问题,就是我们是属于硬件厂商提供硬件和基于我们自己平台的sdk基础提供android系统软件的,其中launcher主页是第三方开发,但是系统相关的接口,由我们实现,比如设置功能,设置功能提供了系统相关的接口,有些是android没有的比如电视制式,分辨率,画面比例等等接口,这些接口有些是android没有的,所以由我们硬件厂商和芯片厂商对接开发。这种开发都是系统预置app。随着业务发展,以前系统软件是基于Android4.4、Android5.1的,但是最近开始上Android9.0的系统,此时就需要对接9.0的系统设置,因为以前的设置是基于老版本开发的,许多功能实现接口都变化了或者没有了,而且设置用的好多接口都是hide的,hide变化更加大,使用java反射实现代码修改量大。而此时,对于硬件使用方有应用商店,他们的设置软件想使用一款软件兼容多个系统,不想多个设置软件管理,此时开发一款兼容新老版本的设置软件变成了首要任务。

软件现状

目前,设置软件是跟随系统软件,使用Android.mk进行编译的,使用的是framework的jar,不仅正常android的api接口可以访问,也可以使用jar里的hide接口,和hide的类。
但是软件目前实现都是基于4.4,5.1实现,我们也实现了一个9.0的设置,但是与老版本部分接口实现变化较大。包括有线网络,wifi,蓝牙,存储等接口。

需求

探究实现一个系统设置apk,可以既用于老android系统,又可以用与新android系统的兼容性设置app。

实现探究

第一点:软件兼容原则

首先,我们要清楚的是,谷歌android或者什么软件工程里,对于软件以及后续版本兼容性是由一些原则和要求的,比如我第一版软件实现的接口,在被第三方什么的app引用后,我们后续更新的接口软件,要遵循兼容性,而不能直接将接口移除,或者随意改变使用方式,做到向下兼容原则,否则这样会对引用接口的app开发维护变得困难。这也是android系统api的遵循方式,首先,我们通过AndroidStudio的编译app使用android接口,默认使用的都是android编译出的标准api,这些api都不是hide类型的api和类,对外的,显然就要接口更加稳定,接口不能轻易改变或者删除,尽量是增加接口,也不删除接口,否则会造成引用应用的不稳定问题。就是尽量实现向下兼容。
因此,我们可以在一般apk里,使用老的一般性api的apk,可以运行在高版本的api的android系统里。而高版本api实现的apk,不能运行在老版本的api版本里。
同时,我们实现尽量不用反射去实现一些不公开的方法或者类,尤其是android后续会部分接口禁用使用反射。
同时我们还要知道的一点是,android的framework的hide接口,其实是不是对外的,基本是对framework内部使用的,所以随之带来的问题是,hide接口的改变和变化程度,注定会比公开的对外的framework接口要高不少,这一点我们也需要了解。

第二点:软件实现方案

实现方案,最初有几个想法。

  1. 通过反射,实现接口兼容性。
    此方法技术可行,但是实现成本较高,因为新老版本软件差异较大,在软件业务层面可能会大量使用反射,开发和调试维护都不方便。
  2. 能否通过java注解什么的,控制api版本和国内实现。
    此方法,当初,是由于,我们软件通过Build.VERSION.SDK_INT等区分实现不同实现api版本的实现,但是这种方案大部分实现是进行兼容性区别实现,即系统功能实现变化,而老接口在api里也没被删除的情况。
    但是对于设置这种调用hide接口,hide接口变化或者接口不存在的情况,编译是不能通过的,因为编译apk的java文件时候,系统找不到兼容两个版本api的接口,编译会报错。所以此方法行不通。
  3. 通过开发兼容性接口jar包方式,放入apk代码,通过不同系统版本引用对于jar包的接口来实现。
    此方法的具体实现经理了多次尝试,实现了。下面就说明一些如何实现,以及在实现过程中遇到的一些问题。

具体实现

下面描述一下我的具体是如何实现功能的。
首先,我们实现的原理是,根据新老系统sdk的差异,如api19和api28的实现差异,在api19的平台开发编译出对应的jar包settings-compat-api19.jar,在api28的平台开发编译出对应的jar包settings-compat-api28.jar,jar里实现的功能,如下图
在这里插入图片描述
比如getDateFormat,api19的设置使用了getDateFormatForSetting接口,此接口还是hide的,但是api28,这个接口删除了,所以我们就,在api19平台编译实现了CompatUtil里的这个接口:

public static DateFormat getDateFormat(Context context) {
	String[] dateFormats = new String[]{"MM-dd-yyyy", "dd-MM-yyyy", "yyyy-MM-dd"};
	DateFormat currentFormat = android.text.format.DateFormat.getDateFormatForSetting(context, dateFormats[0]);
	return currentFormat;
}

在api28平台编译实现了CompatUtil里的这个接口:

public static DateFormat getDateFormat(Context context) {
	DateFormat currentFormat = android.text.format.DateFormat.getDateFormat(context);
	return currentFormat;
}

实现后,我们把这两个jar包放入代码里引用,实现如下:

if (Build.VERSION.SDK_INT >= 28) {
	Log.d(TAG, "compat28...");
	ApplicationInfo info = MainActivity.this.getApplicationInfo();
    com.sdt.settings.compat28.storage.StorageUtil.getPackageSizeInfo(MainActivity.this, info, statsObserver);
	com.sdt.settings.compat28.CompatUtil.getDateFormat(MainActivity.this);
} else {
	Log.d(TAG, "compat19...");
	com.sdt.settings.compat19.storage.StorageUtil.getPackageSizeInfo(MainActivity.this, "com.test.sdt", statsObserver);
	com.sdt.settings.compat19.CompatUtil.getDateFormat(MainActivity.this);
}

至此代码已经实现了。但是编译我在开发中遇到了一些问题,后续解决了,问题如下。
按思路,我在api19和api29编译出了对应的jar,然后,我在api19平台,代码使用Android.mk进行mmm编译,但是编译出现了问题,就是api29的jar报错:
"jdk1.8编译的高版本的类运行在低版本的jre1.6中,报错class file has wrong version 52.0, should be 50.0"
此问题是因为api19编译系统用的是jdk1.6,而settings-compat-api28.jar编译是用的api28系统里的jdk1.8,所以系统buildtools编译dex时候可能就不能使用。
所以,我又去在api28系统里编译,这样应该就不会又问题了把,因为正常是要兼容老jar包的把,然后编译还是出错,报错:
"“Warning: com.sdt.settings.compat19.CompatUtil: can’t find referenced method ‘java.text.DateFormat getDateFormatForSetting(android.content.Context,java.lang.String)’ in library class android.text.format.DateFormat
Warning: there were 1 unresolved references to library class members.
You probably need to update the library versions.
Alternatively, you may have to specify the option
‘-dontskipnonpubliclibraryclassmembers’.”"

后续在Android.mk添加此两项后可以正常编:
LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PROGUARD_FLAG_FILES := proguard.flags

在proguard.flags里添加:
-dontskipnonpubliclibraryclassmembers

这样就编译通过了,可以在api28系统运行,但是在api19系统里系统签名后安装时候,不能正常安装,
提示:Failure [INSTALL_FAILED_DEXOPT]
然后我看网上出这个错误,修改Android.mk的LOCAL_DEX_PREOPT := false,但是还是不想又提示Failure [INSTALL_FAILED_UID_CHANGED],然后看打印如下:
在这里插入图片描述
看打印,应该是高版本api的buildtools编译的dex,放在低版本安装解析时候出错。至此,使用Android.mk,貌似走不通了。

然后我就尝试了使用AndroidStudio去编译apk,新建了工程,然后也编译通过,然后在两个系统api19和api28都能安装和运行,配置如下:

buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.yjl.myapplication"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }

编译需要使用系统framework的全包引入系统取代默认的sdk.jar

    implementation files('libs\\settings-compat-api19.jar')
    implementation files('libs\\settings-compat-api28.jar')
    provided files('libs\\framework-api28.jar')

至此,兼容任务就完成了。

说明

如果各位大神还有其他实现方案,可以告诉我,相互交流,万分感谢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移动应用程序的开发是一个复杂的过程,需要考虑许多因素,以确保软件的高质量和稳定Android酒店预订系统移动应用程序的开发源代码将涉及使用不同的技术和工具,如Java编程语言、Android SDK、Eclipse开发环境等等。 该应用程序需要满足用户的需求和期望,允许他们快速轻松地浏览酒店信息并对其进行预订。该应用程序将涉及许多基本功能,如登录、注册、搜索酒店、选择入住和退房时间、选择酒店房间类型、选择付款方式等等。 在开发过程中,应确保该应用程序是易于使用的,并且必须兼容不同版本的Android操作系统,以便广泛覆盖手机和平板电脑市场。应采用现代的UI设计技术和对用户友好的应用程序布局,以增加用户体验。 另外,应确保该应用程序具有良好的能和响应,使用户可以快速访问酒店信息和预订。在这方面,应该考虑使用缓存、优化数据库查询和使用较小的图像文件来减少网络带宽使用。 最后,开发人员需要测试该应用程序,以确保其质量和稳定。这将涉及使用测试工具和技术,如JUnit测试框架、Monkey测试等等。测试人员需要模拟不同方案,以确保应用程序在各种情况下的功能正常,并处理任何错误和异常情况。 因此,Android酒店预订系统移动应用程序的开发源代码是一个巨大的项目,需要涉及许多技术和工具,并且需要经过严格测试以确保其质量和稳定

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值