`
lyn111
  • 浏览: 13164 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Android应用开发之(让你的应用向后兼容)

阅读更多
目前市场上存在多种类型的Android设备,它们运行在不同的SDK版本上。对开发者而言,需要考虑向后兼容性的问题,请问你是想让你的应用在多种设备上运行,还是仅在最新的版本上运行呢?大多情况下,答案应该是前者,你既想使用最新的SDK api ,同时又想支持旧设备。

设置minSdkVersion

如果你在应用中使用了新的api,如录制视频(该功能是 Android 1.5 (API Level 3) 提供的新功能),那你需要在application's manifest 中加入 <android:minSdkVersion>属性,确保你的应用不会在低版本的设备上运行,如:你的应用依赖 最低版本为API Level 3, 你需要指定“3” 作为你的最低的SDK版本:

<manifest>

...

<uses-sdk android:minSdkVersion="3" />

...

</manifest>



然而,有时候你会遇到要使用一个有用的,但不是必须的特性的情况,如在有物理键盘设备上使用软件盘,是否可以通过其他途径使你可以使用新特性而在低版本的设备上使用,又不出错呢?



使用反射

假设你想使用一个新特性如:android.os.Debug.dumpHprofData(String filename). 虽然Debug类在Android1.0已经存在,但是这个方法是在Anroid 1.5 (API Level 3)中新增的,如果你想使用用它,在 Android 1.1 或者早期的版上运行就会出错。



简单方式我们可以通过反射使用该方法,需要一次查找和缓存结果在Method对象中,调用Method.invoke执行和解析结果,可以参加如下代码:

public class Reflect {

private static Method mDebug_dumpHprofData;



static {

  initCompatibility();

};



private static void initCompatibility() {

  try {

      mDebug_dumpHprofData = Debug.class.getMethod(

              "dumpHprofData", new Class[] { String.class } );

      /* success, this is a newer device */

  } catch (NoSuchMethodException nsme) {

      /* failure, must be older device */

  }

}



private static void dumpHprofData(String fileName) throws IOException {

  try {

      mDebug_dumpHprofData.invoke(null, fileName);

  } catch (InvocationTargetException ite) {

      /* unpack original exception when possible */

      Throwable cause = ite.getCause();

      if (cause instanceof IOException) {

          throw (IOException) cause;

      } else if (cause instanceof RuntimeException) {

          throw (RuntimeException) cause;

      } else if (cause instanceof Error) {

          throw (Error) cause;

      } else {

          /* unexpected checked exception; wrap and re-throw */

          throw new RuntimeException(ite);

      }

  } catch (IllegalAccessException ie) {

      System.err.println("unexpected " + ie);

  }

}



public void fiddle() {

  if (mDebug_dumpHprofData != null) {

      /* feature is supported */

      try {

          dumpHprofData("/sdcard/dump.hprof");

      } catch (IOException ie) {

          System.err.println("dump failed!");

      }

  } else {

      /* feature not supported, do something else */

      System.out.println("dump not supported");

  }

}

}



使用静态初始化程序调用initCompatibility来查看方法,如果成功,使用一个和原来方法一模一样的私有方法来完成调用,模仿原来的方法返回值(如果有)或者抛出异常,示例中的fiddle方法显示了,应用程序如何选择调用新的api或者使用新的方法做一些不同的操作。

每增加一个你想要调用的方法,你需要添加一个私有的Method字段,字段初始化程序,并封装到类中

当一个方法声明在以前没有定义的类中,这会比较复杂,当然,调用Method.invoke()方法比直接调用个这个方法要慢得多,这些问题可以通过使用包装类来缓解

使用包装类

创建一个类来封装所有新的或者已经存在的类暴露的API,每个包装类中的方法是通过类似原方法方式返回相同结果。

如果目标类和方法存在,你会得到与直接调用类相同的行为,但需要花费少量的开销,如果目标类或方法不存在,包装类的初始化程序会失败。这样应用就要避免对新特性的调用。

假如要添加了下面这个新类:

public class NewClass {

private static int mDiv = 1;



private int mMult;



public static void setGlobalDiv(int div) {

  mDiv = div;

}



public NewClass(int mult) {

  mMult = mult;

}



public int doStuff(int val) {

  return (val * mMult) / mDiv;

}

}

我们根据它创建包装类:

class WrapNewClass {

private NewClass mInstance;



/* class initialization fails when this throws an exception */

static {

  try {

      Class.forName("NewClass");

  } catch (Exception ex) {

      throw new RuntimeException(ex);

  }

}



/* calling here forces class initialization */

public static void checkAvailable() {}



public static void setGlobalDiv(int div) {

  NewClass.setGlobalDiv(div);

}



public WrapNewClass(int mult) {

  mInstance = new NewClass(mult);

}



public int doStuff(int val) {

  return mInstance.doStuff(val);

}

}

在包装类中添加于原始类一样的构造函数与方法,并添加一个静态初始化程序测试新类是否存在,如果NewClass不存在,WrapNewClass会初始化失败,确保包装类不被随意使用,通过方法checkAcailable这种简单的方式进行类初始化,使用方法如下:

public class MyApp {

private static boolean mNewClassAvailable;



/* establish whether the "new" class is available to us */

static {

  try {

      WrapNewClass.checkAvailable();

      mNewClassAvailable = true;

  } catch (Throwable t) {

      mNewClassAvailable = false;

  }

}



public void diddle() {

  if (mNewClassAvailable) {

      WrapNewClass.setGlobalDiv(4);

      WrapNewClass wnc = new WrapNewClass(40);

      System.out.println("newer API is available - " + wnc.doStuff(10));

  } else {

      System.out.println("newer API not available");

  }

}

}

如果checkAvailable 方法调用成功,证明新类存在,如果失败,新类不不存在,需要进行异常处理。需要注意的是如果不存在新类,在执行checkAvailable 前就已经失败,字节码验证器不接受不存在类的引用,此代码是结构化的方式,最终的结果与调用Class.forName验证的异常一致

已存在的包装类新增了方法,你只需要将新方法加入到包装类中,在调用旧方法时,WrapNewClass的静态初始化程序会做一次反射的检查操作

测试很重要

你需要在你的应用支持的版本中进行测试,很明显,你的应用在不同的设备上运行时存在差异, 记住:一定要这样做

你在可以通过模拟器进行版本兼容性测试,Android SDK允许你创建多个不同版本的模拟器,注意不同版本上的差异。
分享到:
评论

相关推荐

    Android移动应用开发(第3版)卷Ⅰ基础篇 (Shane Conder, Lauren Darcey) PDF扫描版

    《Android移动应用开发(第3版)卷Ⅰ:基础篇》涵盖了Android开发从概念、技术到市场推广应用的全部主题,内容包括Android平台概览、Android应用程序设计精髓、Android用户界面设计精髓、Android应用程序设计精髓、...

    android应用开发兼容性问题整理

    资源整理了在android应用开发中遇到的几个兼容性问题,并提供解决思路。其中包括,创建快捷方式、dns解析等。

    Android应用开发案例大全7-12

    Android应用开发案例大全7-12.rar

    Android软件平台架构与应用开发.docx

    Android软件平台架构与应用开发; 2008年9月22日,美国运营商T-Mobile USA在纽约正式发布第一款Google手机T-Mobile G1,该款手机为宏达电制造,是世界上第一部基于真正开放的和完整的移动软件Android操作系统的手机,...

    Dart开发Android应用Sky.zip

    Sky 项目使用网页开发语言 Dart 开发原生 Android 应用,强调应用的运行速度和与 Web 的高度集成。Javascript 已经有 20 年的历史,有很多理念已经跟不上时代,编程体验也很差,因此 Chrome V8 引擎团队开发了 ...

    基于Android平台的应用开发经典案例

    随着Android技术的迅猛发展和日趋成熟,Android操作系统在手持终端中所占比例正逐步上升,其开放性、便携性、良好的兼容性、无缝结合网络通信等特点将使Android操作系统在未来工业领域中也有着广泛的应用。...

    Android应用测试与调试实战

    它从Android应用自动化测试工程师和开发工程师的需求出发,从测试和调试两个维度,针对采用Java、HTML 5、C++&NDK三种Android应用开发方式所需要的测试和调试技术、方法进行了细致而深入的讲解,为Android应用的自动...

    android游戏开发毕业论文

    2 Android平台研究2.1 Android特征 2.2 Android应用的构成2.2.1 活动2.2.2 意图接收器2.2.3 服务2.2.4 内容提供者2.3 Android与iPhone比较2.4 本章小结 3 策划与需求分析 3.1 游戏策划 3.2 美工需求 3.3 功能...

    应用宝(应用宝)

    应用宝(Android)是腾讯应用中心倾力打造的手机应用商店,致力于为用户提供丰富、优质、安全、个性化的安卓软件游戏资源和一站式的下载管理体验,全方位覆盖用户的下载、管理、收藏、分享、社交娱乐等多样化需求 ...

    Android应用开发工具ignition.zip

    ignition 通过提供即用组件和包含许多样板文件的实用类,可以让你的 Android 应用快速起步。ignition 涵盖的区域包括: Widget、Adapter、Dialog 等 UI 组件; 允许编写简单却强大的网络代码...

    Android应用源码之完美!SlidingMenu jar包版demo!不用导包!兼容2.2.zip项目安卓应用源码下载

    兼容2.2.zip项目安卓应用源码下载Android应用源码之完美!SlidingMenu jar包版demo!不用导包!兼容2.2.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Google Android SDK开发范例大全 源码

    本书讲述由浅入深,由Android的基础知识到实际开发应用,结构清晰、语言简洁,非常适合Android的初学者和Android的进阶程序开发者阅读参考。 作者简介编辑 余志龙,来自于手机制造业、电视媒体业、网络、电信产业、...

    Android 系统架构及应用程序开发探索

    随着网络信息技术的飞速发展,互联网为人们的生活带来了很大的...基于此,本文从Android系统的发展现状着手,分析了Android系统的架构设计,随后探讨了基于Android系统的应用程序的开发。以此来供相关人士交流参考。

    Android-获取取手机敏感信息Android6.0之上兼容

    获取取手机敏感信息,Android 6.0之上兼容

    新版Android开发教程.rar

    的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 • 应用程序框架 支持组件的重用与替换 • Dalvik Dalvik Dalvik Dalvik 虚拟机 专为移动设备优化 • ...

    Android平台的音视频聊天应用开发

    支持Android平台设备上的音频即时通讯应用开发 提供Java语言API接口,开放示例源代码 兼容Google、HTC、Moto、Samsung等主流硬件设备 支持iOS、Web、PC等设备和Android之间的互联互通 可开发视频会议、视频聊天、即...

    Android开发实验---通讯录.docx

    Android开发实验---通讯录 实验报告 通讯录 姓名: 学号: 课程名称: 移动应用开发 所在学院: 信息科学与工程学院 专业班级: 计算机 任课教师: Android开发实验---通讯录全文共25页,当前为第1页。 Android开发...

    Android.rar

    Android SDK Platform-Tools 是 Android SDK 的一个组件。它包含与 Android 平台进行...虽然这些工具中的某些新功能仅适用于最新版的 Android,但这些工具是向后兼容的,因此您只需要一个版本的 SDK Platform-Tools。

    基于android studio开发的新闻资讯系统(源码+文档).rar

    基于android studio开发的新闻资讯系统,完美兼容,界面优美,可参赛。 有代码,有报告册(包含实验截图,实验详解,实验功能描述,功能实现,数据库设计,系统框架,系统功能设计,以及需求分析等)一步到位,

Global site tag (gtag.js) - Google Analytics