Android 애플리케이션을 처리 할 때 문제가 발생했습니다. 앱에서 .zip 또는 .dex 클래스를로드하는 것입니다. Classloader
문제는 해결할 수 없습니다. 고마워. 고마워. Zip에서 클래스를로드하려고하는데 프로그램이 시작될 때 클래스 (예 : Android 공급자 또는 이와 비슷한 클래스)를로드해야합니다. 그래서, 예를 들어, 패키지 com.example.androidprovider
및 파일 TestProvider.java를 사용하여 프로그램에 파일을 남겨 두어야합니다.Android 애플리케이션에 사용되는 클래스 로더
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;
}
}
, 나는 패키지 com.example.androidprovider
및 클래스 이름 TestProvider
와 클래스를 패키지. (두 클래스는 서로 다른이고, 두 번째 클래스는 내가 정말 필요로하는 클래스입니다.)
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();
}
는 내가 로그 캣을 확인하지만, 로그는 항상
"TestProvider 텍스트"을 보여줍니다. 따라서 로더 코드가 실패했다는 의미입니다. 그 이유는 내 응용 프로그램 이니셜
com.example.androidprovider.TestProvider
(코드의 첫 번째 부분) 클래스, 그리고 로더가 동일한 패키지와 이름으로 다른 클래스를로드하므로 두 번째 클래스를 성공적으로로드 할 수 없다고 생각합니다.
하지만 실제로 두 번째 클래스를로드해야합니다. 두 번째 수업을 시작하는 데 몇 가지 방법을 사용할 수 있습니까? 감사합니다 ...
감사합니다. 아마도 이것이 잘 작동 할 수 있습니다. 제 예제에서는 첫 번째 TestProviderProxy가 가능한 한 적게 변경되어야합니다. 이 코드는 테스트 코드 일뿐입니다. 실제로는 첫 번째 TestProviderProxy의 소스 코드를 얻을 수 없습니다. 하지만 안드로이드 응용 프로그램의 AndroidMenifest.xml 파일 때문에 초기화해야합니다. 그래서 나는 대체 TestProviderProxy (두 번째)를 써서 실제 TestProviderProxy (첫 번째)를로드해야한다. 나는 대체 TestProviderProxy를 다시 쓰려고 생각하지 않았다. 고마워요! –
그건 그렇고, 반성이 정말로 강력하다는 것을 나는 안다. 그렇다면 런타임 실행 중에 두 번째 클래스를 사용하여 첫 번째 클래스를 다룰 수있는 몇 가지 방법이 있습니까? 리플렉션을 사용하여 시스템 계층의 일부 데이터를 수정하여이 작업을 수행 할 수도 있지만 수정해야 할 데이터의 종류를 알지 못했습니다. 감사. –
나는 아직도 성취하려는 것을 확신하지 못한다. 그러나 그것이 당신을 도왔기를 바란다. 예 반사는 "강력"하지만 시스템 자체가 원시 코드로 실행되고 응용 프로그램이 SandBox에서 실행됩니다. 당신은 단지 "어떤 데이터"를 바꿔서 모든 일을 할 수는 없습니다. – cwin