Dianne Hackborn | abdc840 | 2013-03-15 11:38:38 -0700 | [diff] [blame^] | 1 | <!-- |
| 2 | Copyright 2013 The Android Open Source Project |
| 3 | |
| 4 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | you may not use this file except in compliance with the License. |
| 6 | You may obtain a copy of the License at |
| 7 | |
| 8 | http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | |
| 10 | Unless required by applicable law or agreed to in writing, software |
| 11 | distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | See the License for the specific language governing permissions and |
| 14 | limitations under the License. |
| 15 | --> |
| 16 | |
| 17 | # Android Framework Technical Information |
| 18 | |
| 19 | This document provides some general information about how the Android platform |
| 20 | works that is useful for system integrators. |
| 21 | |
| 22 | # Shared libraries |
| 23 | |
| 24 | System integrators who are building their own system image can optionally |
| 25 | add in their own runtime shared libraries that can be used by applications -- |
| 26 | both other built-in applications as well as regular third party applications. |
| 27 | A shared library is identified with a unique name, following standard Java-style |
| 28 | naming conventions. Applications link to these libraries using the |
| 29 | [uses-library](http://developer.android.com/guide/topics/manifest/uses-library-element.html) |
| 30 | tag. |
| 31 | |
| 32 | There are two types of shared libraries you can create: traditional simple .jar |
| 33 | libraries, and newer shared libraries that are bundled in a regular .apk. |
| 34 | |
| 35 | ## Jar libraries |
| 36 | |
| 37 | A jar library is simply a loose jar file placed somewhere on the system image. For |
| 38 | the platform to recognize your library, you will also need to add a file in |
| 39 | `/system/etc/permissions` that declares the shared library. For example, |
| 40 | you may have a `/system/etc/permissions/com.example.mylib.xml` file containing: |
| 41 | |
| 42 | <?xml version="1.0" encoding="utf-8"?> |
| 43 | <permissions> |
| 44 | <library name="com.example.mylib" |
| 45 | file="/system/framework/com.example.mylib.jar" /> |
| 46 | </permissions> |
| 47 | |
| 48 | The jar file itself would then be placed at `/system/framework/com.example.mylib.jar`. |
| 49 | |
| 50 | Note that jar-based shared libraries can not contain Android resources. Any resources |
| 51 | they need will generally need to come from the base platform resources, so if your |
| 52 | library does have resources it is recommended that you use an apk library instead. |
| 53 | These libraries also can not be updated outside of system updates that modify the |
| 54 | system image. If you can live with these limitations, they are the preferred approach, |
| 55 | since they are the most efficient way to provide a shared library. |
| 56 | |
| 57 | ## APK libraries |
| 58 | |
| 59 | Starting with Jelly Bean MR2, Android provides a new shared library feature based |
| 60 | on standard APK files. Implementing such a shared library is easy: include the |
| 61 | [library](http://developer.android.com/guide/topics/manifest/library-element.html) |
| 62 | tag in your apk that is pre-installed on the system image. Android's package manager |
| 63 | will automatically detect this shared library and make it available to other |
| 64 | applications. |
| 65 | |
| 66 | There are some significant advantages to APK-based shared libraries, but they also |
| 67 | have more overhead than jar libraries as well. The additional features you get are: |
| 68 | |
| 69 | + These libraries can also run as a regular Android application. For example, your |
| 70 | apk may primarily consist of a Service that clients interact with. You |
| 71 | can define an aidl interface to that service in the apk, which the service implements |
| 72 | and the library API uses for calling to the service. Bundling this all together in |
| 73 | one apk makes maintenance easier since you know that the internal aidl protocol will |
| 74 | always be consistent between clients and service. |
| 75 | |
| 76 | + These libraries can contain Android resources. Not only can you use them when the |
| 77 | apk operates as a normal app, but you can also access them from clients using the |
| 78 | library. Note, however, that these resources are **not** linked or merged with the |
| 79 | client application's resources -- to access them from within a client application, |
| 80 | you will need to use |
| 81 | [Context.createPackageContext](http://developer.android.com/reference/android/content/Context.html#createPackageContext(java.lang.String, int)). |
| 82 | The client application can not directly access these resources, so you can not do |
| 83 | things like publish XML attribute or drawable resources that the app could reference |
| 84 | in its layout files. |
| 85 | |
| 86 | + You can deliver updates to these libraries outside of core system updates. Since |
| 87 | this is just a regular apk, you can update the library through the normal mechanism |
| 88 | of installing updated applications. When this is done, all client processes will be |
| 89 | killed and use the new version of the library the next time they run. |
| 90 | |
| 91 | There are also some limitations and down-sides to apk libraries that you should be |
| 92 | aware of: |
| 93 | |
| 94 | + Pre-installed applications that link against an apk library can not be installed |
| 95 | as a pre-dexopt on the system image. They must exist as their full apk, with the |
| 96 | platform generating the dexopt file into /data at first boot. This is required because |
| 97 | the library can change on the application, requiring that it be re-linked to it, |
| 98 | which would break the application if it is in its pre-dexopt form (which on the system |
| 99 | image means the apk doesn't contain the .dex code in the apk, and it has the final |
| 100 | .odex file next to it which is directly used when running). |
| 101 | |
| 102 | + When an update to the shared library apk is installed, all client applications |
| 103 | must be re-dexopt'd in addition to the library apk itself. If there are many |
| 104 | client applications, this means that installing a library update can take a significant |
| 105 | amount of time. This will also result in any processes currently using the library |
| 106 | being killed -- for example if a music app is currently playing music and links to |
| 107 | the library, playback will be disrupted during the install. |
| 108 | |
| 109 | + Updates to system apks can not add new shared libraries to the apk. You must declare |
| 110 | the available libraries in the apk that is on the system image; if you want to add any |
| 111 | libraries to an apk you must update it on the system image. This is done to avoid getting |
| 112 | into bad situations for example if the user uninstalls updates to the apk -- without such |
| 113 | a restriction, a newer update an be uninstalled, removing the new shared library and breaking |
| 114 | any applications depending on it that had been allowed to be installed when the library |
| 115 | was there. |
| 116 | |
| 117 | ## Library versioning |
| 118 | |
| 119 | Android does not provide any support for versioning shared libraries, besides the normal |
| 120 | application versioning available if you are using an apk library. The base implementation |
| 121 | of your shared library should always provide the necessary APIs for applications to check |
| 122 | its version. A typical API for an apk shared library would look like: |
| 123 | |
| 124 | public class SharedLibraryMain { |
| 125 | static String LIBRARY_PACKAGE = "com.google.android.test.shared_library"; |
| 126 | |
| 127 | /** |
| 128 | * Base version of the library. |
| 129 | */ |
| 130 | public static int VERSION_BASE = 1; |
| 131 | |
| 132 | /** |
| 133 | * The second version of the library. |
| 134 | */ |
| 135 | public static int VERSION_SECOND = 2; |
| 136 | |
| 137 | /** |
| 138 | * Return the version number of the currently installed library. |
| 139 | */ |
| 140 | public static int getVersion(Context context) { |
| 141 | PackageInfo pi = null; |
| 142 | try { |
| 143 | pi = context.getPackageManager().getPackageInfo(LIBRARY_PACKAGE, 0); |
| 144 | return pi.versionCode; |
| 145 | } catch (PackageManager.NameNotFoundException e) { |
| 146 | throw new IllegalStateException("Can't find my package!", e); |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | /** |
| 151 | * Check that the library's version is at least the given minimum version, |
| 152 | * displaying a dialog to have the user install an update if that is not true. |
| 153 | * The dialog is displayed as a DialogFragment in your activity if a newer |
| 154 | * version is needed. If a newer version is needed, false is returned. |
| 155 | */ |
| 156 | public static boolean ensureVersion(final Activity activity, int minVersion) { |
| 157 | final FragmentManager fm = activity.getFragmentManager(); |
| 158 | final String dialogTag = LIBRARY_PACKAGE + ":version"; |
| 159 | Fragment curDialog = fm.findFragmentByTag(dialogTag); |
| 160 | |
| 161 | if (getVersion(activity) >= minVersion) { |
| 162 | // Library version is sufficient. Make sure any version dialog |
| 163 | // we had shown is removed before returning. |
| 164 | if (curDialog != null) { |
| 165 | fm.beginTransaction().remove(curDialog).commitAllowingStateLoss(); |
| 166 | } |
| 167 | return true; |
| 168 | } |
| 169 | |
| 170 | // The current version of the library does not meet the required version. |
| 171 | // If we don't already have a version dialog displayed, display it now. |
| 172 | if (curDialog == null) { |
| 173 | curDialog = new VersionDialog(); |
| 174 | fm.beginTransaction().add(curDialog, dialogTag).commitAllowingStateLoss(); |
| 175 | } |
| 176 | |
| 177 | // Tell the caller that the current version is not sufficient. |
| 178 | return false; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | If you are writing a simple jar library, you will need to put the current version as |
| 183 | a contant in the code of the library intead of pulling it from the apk version. |
| 184 | |
| 185 | ## Library samples |
| 186 | |
| 187 | Complete samples of an apk library and client can be found in the Android source tree |
| 188 | at `frameworks/base/tests/SharedLibrary`. |