This is a simple project providing incremental updating facilities for android apps.
With the updating feature, you can update your app, which has already been installed on your users' android devices, dynamically at any time. With dynamically updating, you'll no more need to depend on the app market to update your app, you'll no more need to send new version of your app to app market to review or release. This feature is so great if you release your app frequently, and want new features delivered to your users as soon as possible.
With the incremental updating feature, your users only need to download the changes from his old version to the new version to start the app. This will help your user save a lot of time and money.
But, there are also some limitations for incremental updating:
These features are urgently needed especially by games developed in c++.
As we all know, Android provides native code development ability for developers. When we write code in native code (c or c++), Android build tools will compile the code into .so
file, and Android app load them while running. In fact, we can update the so file before running the app, then the app can run with newer code now. Dynamically app updating achieved!
Thanks to bsdiff and bspatch tools, we can use bsdiff to generate the changes between two different binary files, and use bspatch with the patch file and old file to generate the new file. With these tools, incremental app updating achieved!
├── client // all source code needed by client
│ ├── droid-inc-update // lib android project that app must integrate
│ ├── droid-inc-update-demo // a simple demo
│ ├── droid-inc-update-demo-cocos // a cocos2dx demo with incremental updating functionality
│ ├── incupdatedata // directory to save the generated updating files
│ └── tools // tools needed to generate updating files
│ ├── binding_gen.py // tool to generate cocos2dx binding code
│ ├── env.py // settings used across all the tools
│ ├── update_client_res_version.py // tool to update version of client resources
│ ├── update_limit.py // tool to update updating limit of a new version
│ ├── zip_update.py // tool to generate a new incupdate version of your app.
└── server
├── config // config files
├── deploy.sh // deploy script
├── npm-install.sh // npm install script
└── src // server source code written in nodejs
zip_update.py
tool scans all of your resources in the assets/incupdatelibs
and assets/res
directories to generate a version of the resources, then save some information to file assets/files.conf
and assets/incupdate.conf
in JSON format. The version actually is a new release version. The tool also backup the resources and generate a update.zip
file for all older versions. The update.zip
file contains everything needed to update from an old version to the new version.update_limit.py
tool update the updatelimit.json
file in the incupdatedata
directory, which contains updating limit settings of the version, like only app running in Android 5.0 can be updated. The server will read the updateLimit.json
file to delivery the new version correctly.assets/files.conf
or assets/incupdate.conf
. Then the server checks the version and other device information to determine if the client need updating. If needs, the server will send the update.zip
to the app, and the app will complete the updating process with the data contains in update.zip
file.android.library.reference.1=relative/path/to/droid-inc-update
Write bindings in c for all your native methods declared in Java code, and generate loader.so
file. Why is this required? If you use System.loadLibrary
or System.load
API to load your .so
file, it will not be reloaded even if you replace the so file and restart the app. Because Android operating system controls the loading process of .so
file. So, we need a loader.so
to load the real .so
file, and proxy all native methods (This is what called binding before.) used in Java code.
With dlopen
dlsym
dlclose
API, this mechanism will be achieved. Refer client/droid-inc-update-demo/jni/loader.c
to implement your loader.
Build your native code into .so
file, and move .so
file into a directory in assets. Make directory tree like below.
├── assets
│ ├── incupdatelibs // directory to store your `.so` files which need to be updated
│ │ ├── libdemo.so // your compiled `.so` file
│ └── res // root directory of all of your resource files need to be updated
Use client/tools/zip_update.py
to generate a version of all your resource files and .so
files. You may need to change the INCUPDATE_DATA_DIR
setting in the client/tools/env.py
file.
Build your project into an apk. This apk actually supports incremental updating now.
Change source code of your .so
file, like libdemo.so
, and build it. Replace the file in the assets directory (assets/incupdatelibs/libdemo.so
). Use client/tools/zip_update.py
tool to generate a new version of your resources. Start server with incupdata
directory configured. Start the apk which was built in step 5, and you will realize that the changes actually being applied to the apk.
Cocos2d-x binding has already being done by the droid-inc-update project. You can take a look at the code in the client/droid-inc-update/jni/cocosloader
directory. The binding is based on version 2.2.2 of Cocos2d-x. Other versions of Cocos2d-x may need to change something more.
However, Cocos2d-x binding need to change some source code of Cocos2d-x. File cocos2dx/platform/android/CCFileUtilsAndroid.cpp
in the Cocos2d-x root directory need to be replaced with client/cocos-changes/CCFileUtilsAndroid.cpp
. Directory cocos2dx/platform/android/java/src/
need to be replaced with client/java
. These changes should be done, because Cocos2d-x load resources from assets/
in the apk, and we need to load newest resource from file system.
Changes in the CCFileUtilsAndroid.cpp
file:
Java_org_cocos2dx_lib_Config_initPath
, add static variable s_assetsPath
s_resDirRootPath
s_useAssets
.CCFileUtilsAndroid::isFileExist
CCFileUtilsAndroid::doGetFileData
to change the resource search path.Changes in the Java code:
Config.java
to initPath from Java code and provides fixPath function for other Java code to change resource in apk assets to resource in file system.If you need to debug the code, and do not want to use the updating feature, you can set com.comeplus.droidincupdate.Config.FORCE_EXTRACT
to true. In this way, you do not need to generate an updating version every time you update your code. Everything will be newest when you build and run your debuggable apk.
Server is developed with nodejs, and makes full use of the asynchrony of nodejs. So, it'll be very efficient and supports high concurrency requests.
Also, this project already provides very useful functionality for you:
API level
or country
timezone
and so on.When you want to test a new feature in a small group of your users, like 10%, or when you want to deliver the new version only to version 5.0 Android users, you can use client/tool/update_limit.py
to limit the delivery.
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型