如何解决Android:从firebase下载的dex无法正常工作:“找不到用于dex位置的原始dex文件”
我是Android开发的新手,我正在尝试从Firebase存储下载动态加载dex文件(因此可以在不更新应用本身的情况下即时更改它)。我正在尝试关注this Medium Article。
但是DexClassloader总是会出现此错误,这似乎是错误下载(下载后文件大小为0MB)的症状:
E/System: java.io.IOException: No original dex files found for dex location /data/user/0/com.example.calculator/cache/Calc1387497247.dex
at dalvik.system.DexFile.openDexFileNative(Native Method)
at dalvik.system.DexFile.openDexFile(DexFile.java:367)
at dalvik.system.DexFile.<init>(DexFile.java:148)
at dalvik.system.DexFile.loadDex(DexFile.java:219)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:362)
at dalvik.system.DexPathList.makeElements(DexPathList.java:313)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:263)
at dalvik.system.DexPathList.<init>(DexPathList.java:126)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:48)
at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:57)
at com.example.calculator.MainActivity.onCreate(MainActivity.java:64)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
我从中篇文章的linked github project中获得了dex。 只是构建项目,然后解压缩并使用dex文件(我尝试使用整个apk,但同样失败) 看起来它下载正常,并且可以在检查时找到临时文件。
我已经尝试了几个stackoverflow问题中的建议。 ex1 ex2 但是什么都没有。
下载后我能够测试文件的大小,它显示临时文件为0 MB。因此,它必须下载不正确,并且该错误是其症状。
我认为我不是唯一尝试遵循本文的人。 因此,如果任何人都有修复程序,或者可以指出我正在运行的github示例项目的方向,将不胜感激。
源代码:MainActivity.java
package com.example.calculator;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseApp;
import com.google.firebase.storage.FileDownloadTask;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import dalvik.system.DexClassLoader;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseApp.initializeApp(this);
FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
StorageReference gsReference = storage.getReferenceFromUrl("gs://dcl-demo.appspot.com/Calc.dex");
Log.e("Cache Dir: ",getCacheDir().getAbsolutePath());
try {
File outputDir = getCacheDir().getAbsoluteFile(); // context being the Activity pointer
File localFile = File.createTempFile("Calc",".dex",outputDir);
gsReference.getFile(localFile);
Log.e("Local File Path: ",localFile.getAbsolutePath());
Log.e("Local File Name: ",localFile.getName());
File file = new File(localFile.getAbsolutePath());
if(file.exists()) {
Log.e("THE FILE EXISTS: ","EXISTS");
}
final DexClassLoader classLoader = new DexClassLoader(localFile.getAbsolutePath(),getCacheDir().getAbsolutePath(),null,this.getClass().getClassLoader());
try {
Class<?> myOwnClass = classLoader.loadClass("com.example.calculator.DynamicCalculator");
Method addMethod = myOwnClass.getmethod("add",Double.class,Double.class);
double result = (double) addMethod.invoke(null,5.0,3.0);
Log.e("Returned Result: ",String.valueOf(result));
} catch (Exception e) {
e.printstacktrace();
}
} catch (Exception e) {
e.printstacktrace();
}
}}
BuildGradle(应用程序):
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
android {
compileSdkVersion 29
buildToolsversion "30.0.0"
defaultConfig {
applicationId "com.example.calculator"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled false
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),'proguard-rules.pro'
}
}
}
dependencies {
implementation filetree(dir: 'libs',include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
//implementation 'com.google.firebase:firebase-analytics:17.5.0'
implementation 'com.google.firebase:firebase-storage:19.2.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
BuildGradle(项目):
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.google.gms:google-services:4.3.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.calculator">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。