Androidダイナミックローディング


本論文は、http://www.cnblogs.com/over140/archive/2011/11/23/2259367.html
1.android動的ローディングjarバッグ
    a.javaプロジェクトの新規作成
        インターフェースを作成:
package com.example.testload;

public interface IDynamic {
    public String helloWorld();
}
       このインターフェースを実現するクラスを作成します。
package com.test.jarload;

public class DynamicTest implements IDynamic {

    @Override
    public String helloWorld() {
        return "Hello World!";
    }
}
はその後、javaプロジェクトをjarファイルにエクスポートします。ここで私が導き出すのはload.jarの注意です。
jarファイルをエクスポートするときは、インターフェースオプションをチェックしないでください。
 
     Androidプロジェクトでは、jarファイルを直接実行することはできませんので、Androidから提供されたdxを利用して変換する必要があります。 
     sdkのディレクトリに入ると、dxファイルが見つかります。ほとんどのsdkのdxファイルはplaytform-toolsフォルダの下にあります。build-toolsフォルダの下にもいくつかあります。つまり、dxファイルが含まれているフォルダに入って、私達が以前に導出したjarファイルload.jarをディレクトリにコピーして、コマンドラインでこのディレクトリに入り、dxを実行します。 --dex --Output=test.jar load.jarはこのディレクトリの下でtest.jarファイルを生成していることを発見します。このファイルはアンディプロジェクトがロードできるファイルです。このファイルをsdcardのルートディレクトリにコピーします。
   
    新しいandroidプロジェクト:
    コードは簡単です。以下の通りです。
    まず、前のインターフェースをこのプロジェクトでもう一度声明する必要があります。
    
public interface IDynamic {
    public String helloWorld();
}
    MainActivityのコードは簡単です。直接コードを貼ります。
 
 mToastButton = (Button) findViewById(R.id.toast_button);
        
        mToastButton.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("NewApi")
			public void onClick(View view) {
                final File optimizedDexOutputPath = new File(Environment.getExternalStorageDirectory().toString()
                    + File.separator + "test.jar");
                String path = optimizedDexOutputPath.getAbsolutePath();
                DexClassLoader cl = new DexClassLoader(optimizedDexOutputPath.getAbsolutePath(),
                    Environment.getExternalStorageDirectory().toString(), null, getClassLoader());
                Class libProviderClazz = null;
                
                try {
                    libProviderClazz = cl.loadClass("com.test.jarload.DynamicTest");
                    
                    IDynamic lib = (IDynamic)libProviderClazz.newInstance();
                    
                    Toast.makeText(MainActivity.this, lib.helloWorld(), Toast.LENGTH_SHORT).show();
                } catch (Exception exception) {
                    exception.printStackTrace();
                }
            }
        });
Androidにインストールされていないアプリファイルを動的にロードします。
    まずアンディランドプロジェクトを新設し、次のようにactivityを作成します。
public class TestBActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public String getMoney() {
        return "1";
    }

}
そして、このandroidプロジェクトをappkファイル(test.appk)に包装し、sdcardのルートディレクトリにコピーする。
     そして、他のandroidプロジェクトを新たに作成して、以前にエクスポートしたappkファイルをロードするために使用します。
    主なコードは以下の通りです。
        String path = Environment.getExternalStorageDirectory() + "/";
        String filename = "test.apk";
        DexClassLoader classLoader = new DexClassLoader(path + filename, path,
                null, getClassLoader());

        try {
            Class mLoadClass = classLoader.loadClass("com.nmbb.TestBActivity");
            Constructor constructor = mLoadClass.getConstructor(new Class[] {});
            Object TestBActivity = constructor.newInstance(new Object[] {});
            
            Method getMoney = mLoadClass.getMethod("getMoney", null);
            getMoney.setAccessible(true);
            Object money = getMoney.invoke(TestBActivity, null);
            Toast.makeText(this, money.toString(), Toast.LENGTH_LONG).show();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
      注意:以上は、Jarファイルを動的に実行しても、appkファイルを実行しても、sdcardの読み取り権限を追加する必要があります。
<uses-permission android:name=「android.permission.READ幁EXTERNALSTORAGE」/>