【问题标题】:How to catch java exceptions in Delphi code如何在 Delphi 代码中捕获 java 异常
【发布时间】:2019-12-28 10:32:01
【问题描述】:

我正在编写一个通过 JNI 访问 Google Drive API 的 Delphi/Android 应用程序。我需要调用 Java 方法并捕获发生的任何异常。那么如何在 Delphi 中捕获 Java 异常呢?我还需要异常对象来从中获取意图。

我在网上搜索了一些关于Env ExceptionCheck的信息。我想我可以通过这种方式获取异常类,但是如何获取异常对象呢?

Java 代码如下所示:

try {
    new Builder(
        AndroidHttp.newCompatibleTransport(),
        new GsonFactory(),
        DriveLoginFragment.this.mCredential
    ).setApplicationName("My App").build();
}
catch (UserRecoverableAuthIOException e) {
    DriveLoginFragment.this.startActivityForResult(
        e.getIntent(),
        REQUEST_ACCOUNT_PICKER);
    return null;
}

Delphi 代码如下所示:

Drive := TJDrive_Builder.JavaClass.init(
  TJAndroidHttp.JavaClass.newCompatibleTransport,
  TJGsonFactory.JavaClass.init,
  GoogleAccountCredential
)
.setApplicationName(StringToJString('My app'))
.build;

【问题讨论】:

  • 你能描述一下一旦你有了异常对象你将如何处理它?
  • 我想开始一个有意图的活动。如果您查看 javacode,当它捕获到 UserRecoverableAuthIOException 时,它会从异常对象中获取意图,并发出带有此意图的 startActivityforResult。
  • 可能能够在 Thread 类上使用 setDefaultUncaughtExceptionHandler 方法,主要问题是您需要传递覆盖 uncaughtException 方法的 UncaughtExceptionHandler 后代的实例.这需要一些 Java 代码,因为目前 Java 类的后代无法在 Delphi 中完成

标签: java android delphi exception


【解决方案1】:

我按照 Dave Nottage 的建议做了。我编写了一点 java 代码。

我用以下类制作了一个 java 库:

package com.softmagic.androidutils;

import java.lang.Thread.UncaughtExceptionHandler;

interface ExpListener {
    void onException(Thread thread, Throwable throwable);

}

public class DelphiHandleExceptions implements UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable throwable) {
        listenerInt.onException(thread, throwable);
    }

    ExpListener listenerInt;

    public DelphiHandleExceptions(ExpListener listener) {

        listenerInt = listener;
    }

}

我通过 java2op 运行它,得到以下结果:

unit AndroidApi.JNI.AndroidUtils;

interface

uses
  Androidapi.JNIBridge,
  Androidapi.JNI.JavaTypes;

type
// ===== Forward declarations =====

  Jandroidutils_BuildConfig = interface;//com.softmagic.androidutils.BuildConfig
  JDelphiHandleExceptions = interface;//com.softmagic.androidutils.DelphiHandleExceptions
  JExpListener = interface;//com.softmagic.androidutils.ExpListener

// ===== Interface declarations =====

  Jandroidutils_BuildConfigClass = interface(JObjectClass)
    ['{EE706AD2-1C35-46DF-BA16-6B6C82A32336}']
    {class} function _GetAPPLICATION_ID: JString; cdecl;
    {class} function _GetBUILD_TYPE: JString; cdecl;
    {class} function _GetDEBUG: Boolean; cdecl;
    {class} function _GetFLAVOR: JString; cdecl;
    {class} function _GetVERSION_CODE: Integer; cdecl;
    {class} function _GetVERSION_NAME: JString; cdecl;
    {class} function init: Jandroidutils_BuildConfig; cdecl;//Deprecated
    {class} property APPLICATION_ID: JString read _GetAPPLICATION_ID;
    {class} property BUILD_TYPE: JString read _GetBUILD_TYPE;
    {class} property DEBUG: Boolean read _GetDEBUG;
    {class} property FLAVOR: JString read _GetFLAVOR;
    {class} property VERSION_CODE: Integer read _GetVERSION_CODE;
    {class} property VERSION_NAME: JString read _GetVERSION_NAME;
  end;

  [JavaSignature('com/softmagic/androidutils/BuildConfig')]
  Jandroidutils_BuildConfig = interface(JObject)
    ['{2F38FDFA-A06E-486C-A2F1-9736596BFD14}']
  end;
  TJandroidutils_BuildConfig = class(TJavaGenericImport<Jandroidutils_BuildConfigClass, Jandroidutils_BuildConfig>) end;

  JDelphiHandleExceptionsClass = interface(JThread_UncaughtExceptionHandlerClass)
    ['{E39A8542-DF8B-4880-8286-C4BD9993F6CE}']
    {class} function init(P1: JExpListener): JDelphiHandleExceptions; cdecl;//Deprecated
    {class} procedure uncaughtException(P1: JThread; P2: JThrowable); cdecl;//Deprecated
  end;

  [JavaSignature('com/softmagic/androidutils/DelphiHandleExceptions')]
  JDelphiHandleExceptions = interface(JThread_UncaughtExceptionHandler)
    ['{B8AC378F-9FCA-4661-95E0-BA73736E6426}']
  end;
  TJDelphiHandleExceptions = class(TJavaGenericImport<JDelphiHandleExceptionsClass, JDelphiHandleExceptions>) end;

  JExpListenerClass = interface(IJavaClass)
    ['{AC1C06C0-B5D4-4952-9076-5AAAE941703C}']
  end;

  [JavaSignature('com/softmagic/androidutils/ExpListener')]
  JExpListener = interface(IJavaInstance)
    ['{DC8FC3DE-029F-4127-90AA-AABC2081B78B}']
    procedure onException(P1: JThread; P2: JThrowable); cdecl;//Deprecated
  end;
  TJExpListener = class(TJavaGenericImport<JExpListenerClass, JExpListener>) end;

implementation

procedure RegisterTypes;
begin
  TRegTypes.RegisterType('AndroidApi.JNI.AndroidUtils.Jandroidutils_BuildConfig', TypeInfo(AndroidApi.JNI.AndroidUtils.Jandroidutils_BuildConfig));
  TRegTypes.RegisterType('AndroidApi.JNI.AndroidUtils.JDelphiHandleExceptions', TypeInfo(AndroidApi.JNI.AndroidUtils.JDelphiHandleExceptions));
  TRegTypes.RegisterType('AndroidApi.JNI.AndroidUtils.JExpListener', TypeInfo(AndroidApi.JNI.AndroidUtils.JExpListener));
end;

initialization
  RegisterTypes;
end.

我做了以下声明:

   JavaExceptionListener: TJavaExceptionListener;
   DefUncaughtExceptionHandler: JThread_UncaughtExceptionHandler;
   DelphiHandleExceptions: JDelphiHandleExceptions;

在我的 FormCreate 方法中我输入了:

   JavaExceptionListener := TJavaExceptionListener.Create;
   DefUncaughtExceptionHandler := TJThread.JavaClass.getDefaultUncaughtExceptionHandler;
   DelphiHandleExceptions := 
   TJDelphiHandleExceptions.JavaClass.init(JavaExceptionListener);
   TJThread.JavaClass.setDefaultUncaughtExceptionHandler(DelphiHandleExceptions);

我定义了监听器:

  TJavaExceptionListener = class(TJavaLocal, JExpListener)
    procedure onException(P1: JThread; P2: JThrowable); cdecl;
  end;

它的方法:

procedure TJavaExceptionListener.onException(P1: JThread; P2: JThrowable);
begin

  if TJNIResolver.IsInstanceOf(P2, TJUserRecoverableAuthIOException.GetClsID)
  then
     begin
        TAndroidHelper.Activity.startActivityForResult(TJUserRecoverableAuthIOException.Wrap(P2).getIntent, REQUEST_ACCOUNT_PICKER);
        Exit;
     end;

  DefUncaughtExceptionHandler.uncaughtException(P1, P2);

end;

我还没有测试过。我的应用程序尚未准备好进行测试。我认为这会奏效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 2020-11-20
    • 2015-09-20
    • 2018-11-18
    • 2010-09-16
    相关资源
    最近更新 更多