简体   繁体   English

Android后向代码兼容性

[英]Android backward code compatibility

I'm developing an app that uses 我正在开发一个使用的应用程序

android.hardware.Camera.parameters.getSupportedPictureSizes() android.hardware.Camera.parameters.getSupportedPictureSizes()

This is only available from SDK version 8 and I would like to be compatible with SDK 4, so I've done this: 这仅适用于SDK版本8,我希望与SDK 4兼容,所以我这样做了:

if(Build.VERSION.SDK_INT >=8){...} if(Build.VERSION.SDK_INT> = 8){...}

But on the emulator, it seams that it tries to check the reference to this function, and it fails: 但是在模拟器上,它会尝试检查对此函数的引用,并且它会失败:

02-02 11:20:10.930: ERROR/dalvikvm(1841): Could not find method android.hardware.Camera$Parameters.getSupportedPictureSizes, referenced from method com.test.demo.CameraCustom.takeAPicture 02-02 11:20:10.930:ERROR / dalvikvm(1841):找不到方法android.hardware.Camera $ Parameters.getSupportedPictureSizes,从方法com.test.demo.CameraCustom.takeAPicture中引用

Any idea about how to solve this backward compatibility issue? 有关如何解决此向后兼容性问题的任何想法?

I've tried to use inkocation with this piece of code inside surfaceChanged. 我试图在surfaceChanged中使用这段代码进行墨迹分配。 Obviously, the code works directly without invokation: 显然,代码可以直接使用而无需调用:

try{
    windowmanager_defaultdisplay_Rotation = getWindowManager().getDefaultDisplay().getClass().getMethod("getRotation");
    Log.v(MainMenu.TAG, "getRotation exist");
}catch(Exception e){
    Log.v(MainMenu.TAG, "getRotation dont exist");
}

try{
    windowmanager_defaultdisplay_Rotation.invoke(null, null);
    Log.v(MainMenu.TAG, "getRotation invoking ok, rotation ");
}catch(Exception e){
    Log.v(MainMenu.TAG, "exception invoking getRotation "+e.toString());
}

I get "getRotation exist" but then "exception invoking getRotation java.lang.NullPointerException. 我得到“getRotation exists”但是“异常调用getRotation java.lang.NullPointerException。

Any idea? 任何想法?

You cannot load code containing calls to getSupportedPictureSizes() on API level 7 and before. 您无法在API级别7及之前加载包含对getSupportedPictureSizes()调用的代码。 Hence, you need to make your decision based upon Build before you load the code containing the version-dependent statement. 因此, 加载包含依赖于版本的语句的代码之前 ,需要根据Build做出决策。

Your options include: 您的选择包括:

  • Disable the menu choice, button, or whatever that leads to the activity that uses getSupportedPictureSizes() , based upon API level 根据API级别禁用菜单选项,按钮或导致使用getSupportedPictureSizes()的活动的任何内容
  • Use conditional class loading or similar techniques to load a suitable implementation based upon API level, where the "suitable implementation" uses getSupportedPictureSizes() only on API level 8 or higher 使用条件类加载或类似技术来加载基于API级别的合适实现,其中“合适的实现”仅在API级别8或更高级别上使用getSupportedPictureSizes()

An example of the latter technique can be seen in this sample project , where I support forward-facing cameras on API level 9, yet still can run on older versions of Android. 这个示例项目中可以看到后一种技术的一个例子,我支持API级别9的前向摄像头,但仍然可以在旧版本的Android上运行。

Ok, the answer provided by Commonsware is correct, especially if you study the excellent sample project he provided. 好的,Commonsware提供的答案是正确的,特别是如果你研究他提供的优秀样本项目。 Also, zegnus was on the right track when he pointed to http://developer.android.com/resources/articles/backward-compatibility.html 此外,当他指向http://developer.android.com/resources/articles/backward-compatibility.html时,zegnus走上正轨。

The key to this though, which is not clear from the other answer, is that you need to compile with the API that supports the features that you need. 但是,从另一个答案中不清楚的关键是,您需要使用支持所需功能的API进行编译。 Otherwise you get errors. 否则你会收到错误。 In Commonsware's example forward-facing cameras is first supported in API level 9 and this is what you must specify in your project to get it to compile. 在Commonsware的示例中,首先在API级别9中支持前向摄像头,这是您必须在项目中指定的才能进行编译。 Then you can use the other techniques described above to test whether the OS where the app is running actually supports the classes and/or methods that you are trying to use. 然后,您可以使用上述其他技术来测试运行应用程序的操作系统是否实际支持您尝试使用的类和/或方法。 If your app is running on an older version of the OS the calls will generate an exception which you can trap and take the appropriate action for the older OS. 如果您的应用程序在较旧版本的操作系统上运行,则调用将生成一个异常,您可以捕获该异常并对旧操作系统采取适当的操作。

For the sake of completeness, here is the code that I used to be compatible with API 7 even though I compiled with API 8, which includes ThumbnailUtils. 为了完整起见,这里是我曾经与API 7兼容的代码,即使我使用API​​ 8编译,其中包括ThumbnailUtils。

import com.Flashum.util.WrapThumbnailUtils;

   public static Bitmap createVideoThumbnail(String filePath, int kind) {
      try {
         WrapThumbnailUtils.checkAvailable(); // will cause exception if ThumbnailUtils not supported
         return WrapThumbnailUtils.createVideoThumbnail(filePath, kind);
      } catch (Exception e) {
         return null;
      }
   }

package com.Flashum.util;

import android.graphics.Bitmap;
import android.media.ThumbnailUtils;

// To be compatible with Android 2.1 need to create
// wrapper class for WrapThumbnailUtils.
public class WrapThumbnailUtils {
   /* class initialization fails when this throws an exception */
   static {
      try {
         Class.forName("android.media.ThumbnailUtils");
      } catch (Exception ex) {
         throw new RuntimeException(ex);
      }
   }

   /* calling here forces class initialization */
   public static void checkAvailable() {}

   public static Bitmap createVideoThumbnail(String filePath, int kind) {
      return ThumbnailUtils.createVideoThumbnail(filePath, kind);
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM