0

我目前正在为 Android 实现一个 WebDAV 客户端,它基于 sardine ( https://github.com/lookfirst/sardine )。Android-Client 针对 API 级别 15(最低 API 级别)。

现在我想通过使用沙丁鱼工厂类来初始化连接,如下所示:

sardine = SardineFactory.begin(user, password);

这段代码嵌入在一个活动中,它将检查凭据是否有效。通过按下 Activity 的 OK 按钮,启动 AsyncTask,其中嵌入了上面的代码行

AsyncTask<ServerCredentials, Void, ServerCredentials> verifyCredentialsTask = new AsyncTask<String[], Void, boolean>(){
            @Override
            protected boolean doInBackground(String[]...c) {
                try {
                   String user = c[0];
                   String password = c[1]
                   sardine = SardineFactory.begin(user, password);
                   return true;
                }
                catch (Exception e) {
                   return false;
                }

            };

            @Override
            protected void onPostExecute(ServerCredentials sc) {
                final Intent intent = new Intent();
                ...

                setAccountAuthenticatorResult(intent.getExtras());
                setResult(RESULT_OK);
                finish();
            }
        };

当我调试 android 应用程序时,我会首先从 SardineFactory 初始化 sardine。如果我越过这条线,就会抛出 ExceptionInInitializerError。虽然有一个 try catch 语句,但整个活动崩溃了,并且在 logcat 窗口中可以看到以下异常跟踪:

E/AndroidRuntime(10996): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime(10996): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(10996):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(10996):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(10996):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime(10996):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
E/AndroidRuntime(10996):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
E/AndroidRuntime(10996):    at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(10996): Caused by: java.lang.ExceptionInInitializerError
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:45)
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:34)
E/AndroidRuntime(10996):    at com.github.sardine.SardineFactory.begin(SardineFactory.java:22)

我已经在网上搜索了答案。ExceptionInInitializerError 的定义是通用的(https://docs.oracle.com/javase/8/docs/api/index.html?java/lang/ExceptionInInitializerError.html)。

如果我将源附加到我引用的 sardine.jar,我可以调试 begin 方法及其重载。最终调用的“开始”方法定义为

public static Sardine begin(String username, String password, ProxySelector proxy)
{
    try {
        return new SardineImpl(username, password, proxy);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

似乎导致了这个问题。

如您所见,我已经使用 try catch 对其进行了修改,以查看是否可以捕获抛出的异常。但是一旦我跨过 SardineImpl 构造器,就会抛出 ExceptionInInitializerError。我没有机会抓住它。

我认为,仍然缺少一些图书馆。我正在通过 Maven 构建脚本(全新安装)在 Eclipse 中构建 sardine.jar。源没有改变,除了我添加了以下缺少的库

ant-1.9.2.jar
commons-codec-1.6.jar
commons-logging-1.1.3.jar
httpclient-4.5.jar
httpcore-4.3.2.jar
slf4j-api-1.7.12.jar
slf4j-jdk14-1.7.12.jar

Eclipse 项目设置(Java Build Path -> Order and Export)中的钩子是为所有外部库设置的。因此,我假设在目标设备上构建和安装 APK 时没有任何遗漏。

有没有人遇到过类似的问题?如何解释 ExceptionInInitializerError 异常?

4

3 回答 3

1

只是为了关闭这个问题。由于我想通过 webdav 访问 ownCloud 实例,我决定放弃 sardine 库并使用本机 ownCloud 库(https://github.com/owncloud/android-library)。这个库包含一个非常好的示例客户端,非常适合我的项目。

谢谢

于 2015-11-18T16:35:19.673 回答
0

我能够通过使用 Sardine 库来克服这个问题,该库已针对 Android 重写为 Android 库项目 ( https://github.com/aflx/Sardine-Android )。我将项目导入到我的 Eclipse 工作区中,构建它并将 bin 子目录中的 jar 文件链接到我的项目中。最后我不得不在项目的设置“构建路径”->“订单和导出”中设置挂钩。

该解决方案解决了上述问题。现在,我更进一步,但仍然得到一个例外。当我尝试使用以下代码行列出远程服务器上的文件和文件夹时

List<DavResource> res = sardine.list(hostName);

我得到一个 NoClassDefFoundError,它告诉我他找不到类 org.simpleframework.xml.core.Persister。

E/AndroidRuntime(26434): Caused by: java.lang.NoClassDefFoundError: org.simpleframework.xml.core.Persister

在 Sardine-Android 的项目设置中,我已将

simple-xml-2.6.2.jar

其中应该包含缺失的类。此外,我在其他网站(http://android.phonesdevelopers.com/1011_19444554/)中读到,可能有必要从构建路径中排除类,因为它们可能与内置类冲突。不幸的是,他们正在使用我还没有使用过的 gradle。我会在网上搜索解决方案,但也许有人知道这样做很热?

于 2015-09-15T06:49:24.557 回答
0

我在尝试让沙丁鱼在 Android 上运行时遇到了类似的问题。我正在使用 Android Studio,使用 SDK 21 构建。我只是下载了 Sardine-Android 源并将它们添加到项目的文件夹/app/src/main/javasimple-xml-2.6.3.jar. /app/libs我正在使用ActionBarActivity. 代码构建没有错误。但是,我在同一行中遇到另一个错误,但不是NoClassDefFoundError

于 2015-10-14T18:35:29.550 回答