{"id":13537613,"url":"https://github.com/umeng/apf","last_synced_at":"2025-04-02T04:31:11.596Z","repository":{"id":7725980,"uuid":"9092063","full_name":"umeng/apf","owner":"umeng","description":"Android Plugin Framework","archived":false,"fork":false,"pushed_at":"2013-04-01T05:31:37.000Z","size":295,"stargazers_count":320,"open_issues_count":1,"forks_count":125,"subscribers_count":65,"default_branch":"master","last_synced_at":"2024-11-03T02:33:08.482Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/umeng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-03-29T04:17:22.000Z","updated_at":"2024-07-22T11:50:36.000Z","dependencies_parsed_at":"2022-09-02T19:41:22.038Z","dependency_job_id":null,"html_url":"https://github.com/umeng/apf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umeng%2Fapf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umeng%2Fapf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umeng%2Fapf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/umeng%2Fapf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/umeng","download_url":"https://codeload.github.com/umeng/apf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246757130,"owners_count":20828833,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T09:01:01.109Z","updated_at":"2025-04-02T04:31:06.585Z","avatar_url":"https://github.com/umeng.png","language":"Java","funding_links":[],"categories":["Java","Libs"],"sub_categories":["\u003cA NAME=\"Framework\"\u003e\u003c/A\u003eFramework"],"readme":"# Android Plugin Framework\n\u003e This project is pre-mature and may be changed very frequently.\n\n## Introduction\n\nAndroid Plugin Framework (APF) aims to providing a flexible, extensible framework, for Android applications, like OSGi for Java applications. App developers can design their Android applications in a totally new way: declar the interface of a application component, put the actual implementations of the component on the remote server, use APF library to load the actual implementations at runtime. In this way, app developers can dynamically update application components, or add features to an already installed application, without requiring the application being updated throught Android System Framework. A typical usage scenario can be skin: designers design various skins for an application according to pre-defined format and then put those skin files online. App users can then find and use skins through `skin store`, without having to installing a new version of the app.   \nAnother using scenario is for game design: design the `hard` level of a game in a different package that can be dynamically load into the game. When an user passes the `low` level of the game, the app can load the `hard` level of game code using APF dynamically. The user gets a seemlessly upgrade experience.\n \nThe project consists 3 major components: \n\n### APF core\nThe core library to find, verify and load plugin code from remote servers. Now, the architecture and the remote server is still pre-mature and is subject to change, so it is not open sourced yet. But it will be soon. \n\n### Plugin Build Scripts\nThe instructions to create your own plugins. Check [Creating Your APF Plugin] for details.\n\n### Example\nExample contains: \n\n1. Host application, Android Application Project. \n2. Plugin Interface, as an Android Library Project\n3. Plugin Implementation, as an Android Application Project\n  \nThere is already an example plugin implementation signed by [Umeng](http://www.umeng.com) and hosted on [Umeng](http://www.umeng.com)'s server side. If you want to try it out and have a different implementation, please contact xuxianming @ umeng.com\n\n\n## Creating Your APF Plugin\nTo create a effective APD plugin, you will need to design plugin interface first in an Android Library Project. Next, implement the declared interface in an Android Application Project. \n\n### Plugin Interface\n* Create an Android Library Project. \n\n```bash\nandroid create lib-project -n com_example_plugin1_ifs -t android-17 -k com.example.plugin1.ifs -p com.example.plugin1.ifs\n```\n\n* Update ant.properties according to the template file `apf-plugin-build/ant.properties.example`\n```bash\n/apf-opensource/com.example.plugin1$ cat ../apf-plugin-build/ant.properties.example \u003e\u003e ant.properties \n```\nThe `ant.properties` looks like:\n\n```bash\n# This file is used to override default values used by the Ant build system.\n#\n# This file must be checked into Version Control Systems, as it is\n# integral to the build system of your project.\n\n# This file is only used by the Ant script.\n\n# You can use this to override default values such as\n#  'source.dir' for the location of your java source folder and\n#  'out.dir' for the location of your output folder.\n\n# You can also use it define how the release builds are signed by declaring\n# the following properties:\n#  'key.store' for the location of your keystore and\n#  'key.alias' for the name of the key to use.\n# The password will be asked during the build when you use the 'release' target.\nkey.store=../apf-plugin-build/debug.keystore\nkey.store.password=android\nkey.alias=androiddebugkey\nkey.alias.password=android\n```\n\n\n* Update `build.xml` according to the template file `build.xml.plugin.ifs.example`\n```bash\napf-opensource/com.example.plugin1.ifs$ cp ../apf-plugin-build/build.xml.plugin.ifs.example build.xml \n```\n\n* Design the interface to be used by the host application. Check: `src/com/example/plugin1/ifs/`\n\n### Plugin Implementation\n* Create an Android Application Project. \n\n```bash\nandroid create project -n com_example_plugin1 -t android-17 -k com.example.plugin1 -p com.example.plugin1 -a PluginActivity\ncd com.example.plugin1\nandroid update project -p ./ --library ../com.example.plugin1.ifs\n\n```\n\n* Update ant.properties according to the template file `ant.properties.example`\n\n* Update `build.xml` according to the template file `build.xml.plugin.ifs.example`\n```bash\napf-opensource/com.example.plugin1$ cp ../apf-plugin-build/build.xml.plugin.example build.xml \n```\n\n* Design the interface to be used by the host application.\n  `src/com/example/plugin1/ifs/`\n\n\n\n\n\u003e `Plugin Implementation` project will be will packaged/exported as `${package-name}.apk` and `Plugin Interface` project will be packaged to `${package-name}.ifs.jar`.\n\nFor example, `com.umeng.analytics.apk` for plugin, and `com.umeng.analytics.ifs.jar` for interfaces declarations.\n \n### Build\n```bash\n\u003e ant deploy\n```\n\nThe output will be at `${project.dir}/bin/com.example.plugina.apk` and `${project.dir}/bin/com.example.plugina.ifs.jar`.\n                                                             \n\u003e Note: if the plugin implementation projec ifself is a android library project, for example, like com.umeng.common, you need a little \"hack\" to the ant build system. First change ant.properties, change `android.library=true` to `android.library=false`. After successfully `ant deploy`, change it back to `android.library=true`, as is required by the upper stream application project. \n\n### Example\nSee [com.example.host] and [com.example.plugin1]. \n\nTo Run the example: \n```bash\nant \n```\n\n\n\n\n\n\n## Signing plugin\nAll plugins must be signed with private key. APF adopts similar mechanisms as Android app signing. See [Signing Your Applications](http://developer.android.com/tools/publishing/app-signing.html) for help.\n\n### Sign the plugin apk\n\n1. Make sure that you can build your plugin interface and implementation with `ant` successfully before preceeding.\n2. Configure `ant.properties`. Add the content of `ant.properties.example` to your plugin implementation project's `ant.properties`.\n3. Use `ant deploy` to build the release apk package.\nThis will build a *release* mode plugin apk called *[project-name]-release.apk* under bin/ directory. \n\n\n### Warning\n\u003e When to release your plugin, remember to update the key and keystore. Do not use the example key store used here. \n\u003e Caution: Since APF is in very pre-mature state, it's architecture and server side design is subject to change very frequently. For now, APF provided by [Umeng](http://www.umeng.com) does not allow any plugin signed by third party. If you want to try this out and want to deploy your plugin on [Umeng](http://www.umeng.com)'s platform, please develop your plugin first and contact us. After we check out that your plugin is secure, we can sign the plugin for you and host your plugin on  [Umeng](http://www.umeng.com)'s server. Please email to xuxianming at umeng.com. \nWe will open source implementation of APF when it's architecture design is freezed. \n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumeng%2Fapf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fumeng%2Fapf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fumeng%2Fapf/lists"}