gpt4 book ai didi

java - 应用程序卡住、中断并强制关闭 "Uncaught remote exception!"

转载 作者:太空宇宙 更新时间:2023-11-04 12:22:54 26 4
gpt4 key购买 nike

我一直在使用 react-native 开发套接字应用程序和socket.io .

我使用AccountManagerAuthenticator在 Android 上存储用户凭据。

在 Android 中,我听 error (又名 onError )事件。

当套接字连接意外关闭时error事件被触发。

如果error包含EngineIOException: websocket error text 我启动一个处理程序 postDelayed 以再次连接到套接字服务器。

不幸的是,该应用程序在运行时卡住postDelayed代码。然后出现一个对话框窗口,其中包含 App isn't responding - Do you want to close it? - [Wait] [OK] .

如果我按[OK]按钮,几秒钟后就会出现另一个消息框。

我尝试了一整天的调查,但找不到解决方案。

有办法解决这个问题吗?

其他信息

  • 我尝试实现典型的 AutheticatorAndroid 。我有Authenticator.java , AuthenticatorActivity.java , AuthenticatorService.javaAPIServerAuthenticate.java连接套接字服务器的文件。我用ActivityIntent没有 Android View类。
  • 它总是停止Bundle results = future.getResult();线getAuthToken()方法。并且永远不会传递到下一行。我发现通过使用 Log.d()方法。

应用程序崩溃后,ADB logcat 显示以下消息。

I/WindowState(  394): WIN DEATH: Window{52a4aef8 u0 com.rnnativemodules/com.rnnativemodules.MainActivity}
D/dalvikvm( 394): GC_CONCURRENT freed 1912K, 26% free 10997K/14820K, paused 2ms+2ms, total 104ms
W/EGL_genymotion( 690): eglSurfaceAttrib not implemented
D/MobileDataStateTracker( 394): default: setPolicyDataEnable(enabled=true)
I/qtaguid ( 394): Failed write_ctrl(s 0 10083) res=-1 errno=1
W/NetworkManagementSocketTagger( 394): setKernelCountSet(10083, 0) failed with errno -1
I/qtaguid ( 394): Failed write_ctrl(s 1 10023) res=-1 errno=1
W/NetworkManagementSocketTagger( 394): setKernelCountSet(10023, 1) failed with errno -1
W/InputMethodManagerService( 394): Got RemoteException sending setActive(false) notification to pid 16331 uid 10083
D/Sensors ( 394): Client connection accepted (187)
E/Genymotion( 394): Could not open '/sys/class/power_supply/genymotion_fake_path/present'
D/dalvikvm(16391): Late-enabling CheckJNI
I/ActivityManager( 394): Start proc com.rnnativemodules for service com.rnnativemodules/com.customemodule.AuthenticatorService: pid=16391 uid=10083 gids={50083, 3003, 1015, 1028}
W/dalvikvm(16391): Exception Ljava/lang/RuntimeException; thrown while initializing Lcom/facebook/react/bridge/ReactBridge;
W/dalvikvm(16391): Exception Ljava/lang/ExceptionInInitializerError; thrown while initializing Lcom/facebook/react/bridge/NativeMap;
E/JavaBinder(16391): *** Uncaught remote exception! (Exceptions are not yet supported across processes.)
E/JavaBinder(16391): java.lang.ExceptionInInitializerError
E/JavaBinder(16391): at com.facebook.react.bridge.NativeMap.<clinit>(NativeMap.java:22)
E/JavaBinder(16391): at com.customemodule.APIServerAuthenticate.signIn(APIServerAuthenticate.java:56)
E/JavaBinder(16391): at com.customemodule.Authenticator.getAuthToken(Authenticator.java:79)
E/JavaBinder(16391): at android.accounts.AbstractAccountAuthenticator$Transport.getAuthToken(AbstractAccountAuthenticator.java:196)
E/JavaBinder(16391): at android.accounts.IAccountAuthenticator$Stub.onTransact(IAccountAuthenticator.java:113)
E/JavaBinder(16391): at android.os.Binder.execTransact(Binder.java:388)
E/JavaBinder(16391): at dalvik.system.NativeStart.run(Native Method)
E/JavaBinder(16391): Caused by: java.lang.RuntimeException: SoLoader.init() not yet called
E/JavaBinder(16391): at com.facebook.soloader.SoLoader.assertInitialized(SoLoader.java:234)
E/JavaBinder(16391): at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:169)
E/JavaBinder(16391): at com.facebook.react.bridge.ReactBridge.staticInit(ReactBridge.java:39)
E/JavaBinder(16391): at com.facebook.react.bridge.ReactBridge.<clinit>(ReactBridge.java:31)
E/JavaBinder(16391): ... 7 more
W/dalvikvm(16391): threadid=9: thread exiting with uncaught exception (group=0xa4bff648)
E/AndroidRuntime(16391): FATAL EXCEPTION: Binder_1
E/AndroidRuntime(16391): java.lang.ExceptionInInitializerError
E/AndroidRuntime(16391): at com.facebook.react.bridge.NativeMap.<clinit>(NativeMap.java:22)
E/AndroidRuntime(16391): at com.customemodule.APIServerAuthenticate.signIn(APIServerAuthenticate.java:56)
E/AndroidRuntime(16391): at com.customemodule.Authenticator.getAuthToken(Authenticator.java:79)
E/AndroidRuntime(16391): at android.accounts.AbstractAccountAuthenticator$Transport.getAuthToken(AbstractAccountAuthenticator.java:196)
E/AndroidRuntime(16391): at android.accounts.IAccountAuthenticator$Stub.onTransact(IAccountAuthenticator.java:113)
E/AndroidRuntime(16391): at android.os.Binder.execTransact(Binder.java:388)
E/AndroidRuntime(16391): at dalvik.system.NativeStart.run(Native Method)
E/AndroidRuntime(16391): Caused by: java.lang.RuntimeException: SoLoader.init() not yet called
E/AndroidRuntime(16391): at com.facebook.soloader.SoLoader.assertInitialized(SoLoader.java:234)
E/AndroidRuntime(16391): at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:169)
E/AndroidRuntime(16391): at com.facebook.react.bridge.ReactBridge.staticInit(ReactBridge.java:39)
E/AndroidRuntime(16391): at com.facebook.react.bridge.ReactBridge.<clinit>(ReactBridge.java:31)
E/AndroidRuntime(16391): ... 7 more

我的类(class)如下:

public class SocketIO {

final String TAG = "!NativeModules";
final String TAG2 = this.getClass().getSimpleName();
final String ERR_TOKEN = "ERR_TOKEN";
final String ERR_NO_AUTH_HEADER = "ERR_NO_AUTH_HEADER";

private final String SERVER_URL = "http://192.168.1.25:3443";
private final String mAccountType = "api.awesome.mobile";
private final String mAuthTokenType = "FULL_ACCESS";
private final String[] mAuthToken = new String[1];

Boolean areEventsRegistered = false;

// TODO: mActivity and mContext must be changed with Service's Activity and Context
private Activity mActivity;
private ReactApplicationContext mContext;

public SocketIO(ReactApplicationContext context) {
this.mContext = context;
}

private Socket mSocket;
{
try {
IO.Options opts = new IO.Options();
opts.reconnectionDelay = 2000;
opts.reconnectionDelayMax = 14000;
// opts.randomizationFactor = 0.8;
mSocket = IO.socket(SERVER_URL, opts);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}

public Socket getSocket() {
return mSocket;
}

/**
* This method is used for to prevent register the same Listener multiple times.
*/
private void registerEvents () {
if (areEventsRegistered) {
return;
}

// Setting the request header!
mSocket.io().on(Manager.EVENT_TRANSPORT, onTransport);

mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on(Socket.EVENT_ERROR, onError);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on(Socket.EVENT_RECONNECT, onReconnect);
mSocket.on(Socket.EVENT_RECONNECT_ERROR, onReconnectError);

areEventsRegistered = true;
}



private void deregisterEvents () {
if (!areEventsRegistered) {
return;
}

mSocket.io().off(Manager.EVENT_TRANSPORT, onTransport);

mSocket.off(Socket.EVENT_CONNECT, onConnect);
mSocket.off(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.off(Socket.EVENT_ERROR, onError);
mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.off(Socket.EVENT_RECONNECT, onReconnect);
mSocket.off(Socket.EVENT_RECONNECT_ERROR, onReconnectError);

areEventsRegistered = false;
}



public void connect (Activity activity) {

mActivity = activity;

WritableMap results = getAuthToken(mAccountType, mAuthTokenType);
if (results.hasKey(AccountManager.KEY_AUTHTOKEN)) {
mAuthToken[0] = results.getString(AccountManager.KEY_AUTHTOKEN);
registerEvents();
mSocket.connect();
} else {
/**
* ERROR HANDLING
*/
String errorCode = results.getString(AccountManager.KEY_ERROR_CODE);
String errorMessage = results.getString(AccountManager.KEY_ERROR_MESSAGE);
Log.d(TAG, TAG2 + " ---> connect - errorCode: " + errorCode);
/**
* If the error code E_FAILED_TO_CONNECT it means the server is down or cannot
* be reached at the moment. Try again after 30 seconds.
*/
if (errorCode.equals(APIServerAuthenticate.ERROR_FAILED_TO_CONNECT_CODE)) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
connect(mActivity);
}
}, 30000);
}

}
}



public void disconnect (final Activity activity) {
mActivity = activity;
deregisterEvents();
mSocket.disconnect();
}



private Emitter.Listener onTransport = new Emitter.Listener() {
@Override
public void call(Object... args) {
Transport transport = (Transport)args[0];
transport.on(Transport.EVENT_REQUEST_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
@SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>)args[0];
if (mAuthToken[0] != null) {
String bearer = "Bearer " + mAuthToken[0];
headers.put("Authorization", Arrays.asList(bearer));
}
}
}).on(Transport.EVENT_RESPONSE_HEADERS, new Emitter.Listener() {
@Override
public void call(Object... args) {
}
});
}
};



private Emitter.Listener onConnect = new Emitter.Listener() {
@Override
public void call(final Object... args) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {

}
});
}
};


private Emitter.Listener onError = new Emitter.Listener() {
@Override
public void call(final Object... args) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {

// Important!
disconnect(mActivity);

String error = args[0].toString();

if (error.equals(ERR_TOKEN)) {
/**
* If the token sent is invalid the auth server returns ERR_TOKEN error.
* Because of that remove the current authtoken from AccountManager cache.
* Then try to connect again.
*/
if (invalidateAuthToken(mAccountType, mAuthTokenType)) {
connect(mActivity);
}
}
else if (error.contains("EngineIOException: websocket error")) {
/**
* If the socket connection is closed unexpectedly.
* Socket returns an error as "io.socket.engineio.client.EngineIOException:
* websocket error". Try again to connect to the server after 30 seconds.
*/
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
connect(mActivity);
}
}, 30000);
return;
}
}
});
}
};


private Emitter.Listener onConnectError = new Emitter.Listener() {
@Override
public void call(final Object... args) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {

}
});
}
};



private Emitter.Listener onReconnect = new Emitter.Listener() {
@Override
public void call(final Object... args) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
};



private Emitter.Listener onReconnectError = new Emitter.Listener() {
@Override
public void call(final Object... args) {
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
};



/**
* Get the authorization token from the account manager
* @param accountType
* @param authTokenType
*/
public WritableMap getAuthToken(String accountType, String authTokenType) {

AccountManager mAccountManager = AccountManager.get(mContext);

// Finished flag
final boolean[] isFinished = new boolean[1];
final WritableMap response = new WritableNativeMap();
final Account availableAccounts[] = mAccountManager.getAccountsByType(accountType);

if (availableAccounts.length == 0) {
response.putString(AccountManager.KEY_ERROR_CODE, AccountManagerModule.ERROR_NO_ACCOUNT_CODE);
response.putString(AccountManager.KEY_ERROR_MESSAGE, AccountManagerModule.ERROR_NO_ACCOUNT_MESSAGE);
isFinished[0] = true;
} else {
final Account account = availableAccounts[0];
// TODO: activity below must be changed with service activity `getCurrentActivity()``
final AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, mActivity, null, null);

new Thread(new Runnable() {
@Override
public void run() {
try {
Bundle results = future.getResult();
final String authToken = results.getString(AccountManager.KEY_AUTHTOKEN);

// If no error message
if (results.getString(AccountManager.KEY_ERROR_MESSAGE) == null) {
if (authToken == null) {
response.putString(AccountManager.KEY_ERROR_CODE, AccountManagerModule.ERROR_NO_TOKEN_CODE);
response.putString(AccountManager.KEY_ERROR_MESSAGE, AccountManagerModule.ERROR_NO_TOKEN_MESSAGE);
isFinished[0] = true;
} else {
response.putString(AccountManager.KEY_AUTHTOKEN, results.getString(AccountManager.KEY_AUTHTOKEN));
isFinished[0] = true;
}
} else {
response.putString(AccountManager.KEY_ERROR_CODE, results.getString(AccountManager.KEY_ERROR_CODE));
response.putString(AccountManager.KEY_ERROR_MESSAGE, results.getString(AccountManager.KEY_ERROR_MESSAGE));
isFinished[0] = true;
}
} catch (Exception e) {
e.printStackTrace();
response.putString(AccountManager.KEY_ERROR_CODE, AccountManagerModule.ERROR_EXCEPTION_CODE);
response.putString(AccountManager.KEY_ERROR_MESSAGE, e.getMessage());
isFinished[0] = true;
}
}
}).start();

}

//wait for response
while (isFinished[0] == false) {
try{
Thread.sleep(150);
} catch (Exception e) {}
}

return response;

}


/**
* Removes an auth token from the AccountManager's cache. Does nothing if the auth token is not currently in the cache.
* Applications must call this method when the auth token is found to have expired or otherwise become invalid for
* authenticating requests. The AccountManager does not validate or expire cached auth tokens otherwise.
*
* @param accountType
* @param authTokenType
*/
public boolean invalidateAuthToken(String accountType, String authTokenType) {

final AccountManager mAccountManager = AccountManager.get(mContext);

// Finished flag
final boolean[] isFinished = new boolean[1];
final boolean[] response = new boolean[1];
response[0] = false;

// getting the first relevant account!
Account accounts[] = mAccountManager.getAccountsByType(accountType);

if(accounts.length == 0) {
// throw new Exception(AccountManagerModule.ERROR_NO_ACCOUNT_MESSAGE);
Log.d(TAG, TAG2 + " ! " + AccountManagerModule.ERROR_NO_ACCOUNT_MESSAGE);
} else {
final Account account = accounts[0];
final AccountManagerFuture<Bundle> future = mAccountManager.getAuthToken(account, authTokenType, null, mActivity, null,null);

new Thread(new Runnable() {
@Override
public void run() {
try {
Bundle bundle = future.getResult();
final String authtoken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
mAccountManager.invalidateAuthToken(account.type, authtoken);
response[0] = true;
isFinished[0] = true;
} catch (Exception e) {
e.printStackTrace();
isFinished[0] = true;
}
}
}).start();
}

//wait for finishing the ops.
while (isFinished[0] == false) {
try{
Thread.sleep(100);
} catch (Exception e) {}
}

return response[0];

}

}

最佳答案

当通过用户交互启动上面的代码时,new ThreadAsynkTask 与用于 sleep Threadwhile 循环一起正常工作。

但是,当通过系统交互运行代码时,应用程序被卡住。未响应。

我的解决方法是将具有异步任务或创建新线程的代码(在本例中为 getAuthToken() 内容)移动到相关方法中。然后我删除了 while 循环来等待异步结果。我在异步部分为我的应用程序提供了指导。

这对我有用。

关于java - 应用程序卡住、中断并强制关闭 "Uncaught remote exception!",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38647657/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com