GithubHelp home page GithubHelp logo

charslab / android-hotpatch Goto Github PK

View Code? Open in Web Editor NEW
12.0 3.0 6.0 2.19 MB

Update an android app on the fly

License: MIT License

Java 97.58% Shell 2.42%
android hotpatch autoupdate hotfix apk jar

android-hotpatch's Introduction

Android-Hotpatch

Github All Releases license gitcheese.com

Update or fix an android app on the fly, without having to publish a new APK.

Usage:

  1. Make a .jar library with your app's classes and methods that you want to be updatable (see compiling your application as a library)
  2. Grab Hotpatch.java and add it to your project
  3. Load the .jar library you built earlier

You might need to do a small refactor of your app's code, but the advantages are many:

  • Quickly fix & deploy a patch for a method
  • Add methods to classes
  • Hotpatch does not need the app to restart
  • Updating an app using Hotpatch does not require root!

Dependencies:

okhttp (>= 3.8.1)

Add it to your gradle files:

 compile 'com.squareup.okhttp3:okhttp:3.8.1'

Quick usage demo:

Let's say we have a class that we want to use in our Android app, defined this way:

package com.chars.testlib;

public class TestLib {
     public String getVersionString() {
        return "libversion 1.0";
     }
}

After making a .jar library of that class, deploy it to your device i.e in your app private storage path (getFilesDir())

In order to use it in your Android app, you must load it with Hotpatch

final String className = "com.chars.testlib.TestLib";
final String methods[] = {"getVersionString"};

final Hotpatch hotpatch = new Hotpatch();

try {
    hotpatch.loadLibrary(getFilesDir() + "/TestLib.jar", getApplicationContext());
    hotpatch.loadClass(className);
    hotpatch.loadMethods(className, methods);

    String result = (String)hotpatch.call(className, methods[0]);
    Log.d("AndroidHotpatch", result);

} catch (Exception e) {
    Log.e("AndroidHotpatch", Log.getStackTraceString(e));
}

The line

    String result = (String)hotpatch.call(className, methods[0]);

will execute the getVersionString() method, defined in class TestLib.

To update the library, just make a new .jar from an updated version of the class. For example:

package com.chars.testlib.TestLib;

public class TestLib {
     public String getVersionString() {
        return "libversion 2.0";
     }
}

Push the updated .jar to the same path as the previous. In your Android app, you can just call

    hotpatch.reload();

and you'll have your updated library loaded into the app. Now, whenever you execute getVersionString() you will get "libversion 2.0"

OTA Update

To patch or update your app remotely, you have to setup trusted domains first. This prevents attacks like DNS spoofing. While downloading the patch file, Android-Hotpatch will perform certificate pinning, to make sure the patch is being dowloaded from your server.

  1. Obtain your server's certificate publick key:

    You can obtain the sha256-hashed public key of your certificate with:

    ./get_key_sha256.sh yourdomain.com
    

    For example, using github.com:

    ./get_key_sha256.sh github.com
    

    The output will be:

    /businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Delaware/serialNumber=5157550/street=88 Colin P Kelly, Jr Street/postalCode=94107/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=github.com
    pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
    /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA
    RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
    

    pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU= is the hashed public key.

  2. Add trusted domain name to Android-Hotpatch domains list

    Add the domain-key pair to Android-Hotpatch:

    hotpatch.addSecureDomain("https://github.com", "sha256/pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=");

    Note: prepend the hash you obtained in the previous step with 'sha256/'

  3. Download and apply patch file

    You can now download your updated patch from your domain with

    hotpatch.downloadHotpatch("https://yourdomain.com/url/to/patch.jar", path, callback);

    Example:

    hotpatch.downloadHotpatch("https://github.com/charslab/Android-Hotpatch/raw/master/TestLib/testlib_v2.0.jar",
                      hotpatchPath,
                      new Hotpatch.Callback() {
                          @Override
                          public void run() {
                              try {
                                  hotpatch.reload();
                                  Log.d("AndroidHotpatch", "Hotpatch update completed");
    
                                  String result = (String) hotpatch.call(className, methods[0]);
                                  Intent update_text = new Intent("update-textview");
                                  update_text.putExtra("version", result);
                                  sendBroadcast(update_text);
                              } catch (Exception e) {
                                  Log.e("AndroidHotpatch", Log.getStackTraceString(e));
                                  textViewResult.setText(e.getMessage());
                              }
    
                          }
    });

See MainActivity.java for usage example.

Compiling an application as a library (Android Studio / Eclipse):

  1. Start a new android project
  2. Add the classes that you want to be updatable
  3. Build an APK
  4. Rename the .apk file to .jar

Changelog

  • v1.0 Beta:

    • Certificate pinning for OTA updates
    • Bugfixes
  • v1.0 Alpha:

    • Support for methods
    • Implemented Hotpatch.loadLibrary()
    • Implemented Hotpatch.loadClass()
    • Implemented Hotpatch.loadMethods()
    • Implemented Hotpatch.reload()
    • Implemented Hotpatch.call()

android-hotpatch's People

Contributors

carloalbertobarbano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

android-hotpatch's Issues

google play service

hi
i tryed many time but i get the same error
E/GooglePlayServicesUtil: The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.

how to get context from loaded class

i have a class that use SharedPreferences but i get this error related to app context
Attempt to invoke virtual method 'android.content.SharedPreferences
android.content.Context.getSharedPreferences

and also some other function taht use context
do you have a work around for this issue
thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.