1

Android アプリケーションを扱う際に厄介な問題に遭遇しました - アプリ内の .zip または .dex からクラスをロードします。Classloader私はその問題に対処できません。助けてください、ありがとう。zip からクラスをロードしようとしていますが、プログラムの開始時にクラス (Android プロバイダーなど) をロードする必要があります。そのため、パッケージcom.example.androidproviderやファイル TestProvider.java などのファイルをプログラムに残す必要があります。

package com.example.androidprovider;
public class TestProvider extends ContentProvider {
public static final String AUTHORY="com.lcz.tst";
      DBHelper dbHelp;
      SQLiteDatabase sq;
      @Override
      public int delete(Uri uri, String selection, String[] selectionArgs) {
                sq.delete(DBHelper.TABLE, selection, selectionArgs);
                return 0;
      }
      ...
      @Override
      public boolean onCreate() {
                dbHelp=new DBHelper(getContext(),null, null, 1);
                sq=dbHelp.getWritableDatabase();
                Log.i("TestProvider", "text");
                return true;
      }
}

私の .zip ファイルでは、packagecom.example.androidproviderと class nameを使用してクラスをパッケージ化しTestProviderます (2 つのクラスは異なり、2 番目のクラスは本当に必要なクラスです)。

package com.example.androidprovider;
public class TestProvider extends ContentProvider {
      public static final String AUTHORY="com.lcz.tst";
      DBHelper dbHelp;
      SQLiteDatabase sq;
      @Override
      public int delete(Uri uri, String selection, String[] selectionArgs) {
                sq.delete(DBHelper.TABLE, selection, selectionArgs);
                return 0;
      }
      ...
      @Override
      public boolean onCreate() {
                dbHelp=new DBHelper(getContext(),null, null, 1);
                sq=dbHelp.getWritableDatabase();
                Log.i("Original Provider", "This is the original!!!");
                return true;
      }
}

さて、これが私のローダーコードです。

public void loadDex(String strActivity){
      final File optimizedDexOutputPath = oriActivity.getDir("outdex", Context.MODE_PRIVATE);
      // Initialize the class loader with the secondary dex file.
      //dexInternalStoragePath.getAbsolutePath() is the path there the .zip is,
      DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
                optimizedDexOutputPath.getAbsolutePath(),
                libPath,
                this.getClass().getClassLoader());
      Class<?> cls;
      try {
                cls = cl.loadClass("com.example.androidprovider.TestProvider");
                Object instant = cls.newInstance();
                Method method = cls.getDeclaredMethod("onCreate");
                method.invoke(instant);
      }catch (Exception e) {
                e.printStackTrace();
      }

logcat を確認しましたが、ログには常に"TestProvider text"が表示されます。つまり、これは私のローダー コードが失敗したことを意味します。その理由は、私のアプリケーションがcom.example.androidprovider.TestProvider(コードの最初の部分) クラスをイニシャルし、ローダーが同じパッケージと名前の別のクラスをロードするため、2 番目のクラスを正常にロードできないためだと思います。

しかし、私は本当に2番目のクラスをロードする必要があります. 2 番目のクラスを開始するためにいくつかの方法を使用できますか? ありがとう...

4

2 に答える 2

1

これを行うよりクリーンな方法は、Application クラスで attachBaseContext() をオーバーライドして、基本コンテキストのクラスローダーを変更することです。

protected void attachBaseContext(Context base)
{
   Log.i(loggerName, "Attaching base context");
   super.attachBaseContext(base);

   // Modify base.getClassLoader() via reflection.
   // Load classes as normal without having to tinker around with loadClass etc.

}
于 2014-01-26T10:59:08.210 に答える