- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在使用 react-native
开发套接字应用程序和socket.io
.
我使用AccountManager
和Authenticator
在 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]
按钮,几秒钟后就会出现另一个消息框。
我尝试了一整天的调查,但找不到解决方案。
有办法解决这个问题吗?
其他信息
Autheticator
上Android
。我有Authenticator.java
, AuthenticatorActivity.java
, AuthenticatorService.java
和APIServerAuthenticate.java
连接套接字服务器的文件。我用Activity
和Intent
没有 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 Thread
或 AsynkTask
与用于 sleep Thread
的 while
循环一起正常工作。
但是,当通过系统交互运行代码时,应用程序被卡住。未响应。
我的解决方法是将具有异步任务或创建新线程的代码(在本例中为 getAuthToken()
内容)移动到相关方法中。然后我删除了 while 循环来等待异步结果。我在异步部分为我的应用程序提供了指导。
这对我有用。
关于java - 应用程序卡住、中断并强制关闭 "Uncaught remote exception!",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38647657/
你好我是 Angular JS 的初学者,当我开始创建模块和 Controller 时,我无法打印我的消息,下面是我的代码 var myModule = angular.module("myFirst
我对 JQuery 还是个新手,我正在尝试使用它遍历 JSON 数组并使用数组中的数据更新我的网页。 JSON 文件如下所示: [ { "firstname":"John",
我正在使用 AngularJS 1.3.5,我正在尝试从 json 文件中获取信息。这是我的代码:HTML 文件: {{da
我正在创建 Bootstrap 模板。我收到两个错误,我不知道自己做错了什么。当我搜索类似的问题时,似乎是脚本错乱了,但我认为它们的位置是正确的。 两个错误: 未捕获的 ReferenceError:
我试图用子菜单制作导航栏,但我一直收到 dropMenu 未定义,当我将鼠标悬停在两个巴黎链接上时,我收到 Uncaught TypeError: Cannot read property 'styl
我正在尝试在名为 UserComponent 的 Angular 组件上运行 karma 测试。在此组件中,我有一个 ngOnInit 执行此操作: ngOnInit() { const
当我启用 login.spec.ts 测试时,对于不同的测试,我总是随机收到此错误。未捕获错误:未捕获( promise ):错误:无法匹配任何路由。 URL 段:“注销” 我尝试使用以下方法伪造 a
自从我设置一个与 Angular 一起运行的网络应用程序以来已经有一段时间了。我正在通过一个旧项目回顾我的步骤(尝试在我正在做的页面上实现一个 Controller ,确保 Controller 文件
在 AWS Elastic Beanstalk 上部署应用程序后会发生此错误。构建和部署成功,所有模块都正常工作,除了一个显示上述 super 表达式错误的模块。一切似乎都在本地机器上正常工作,甚至可
我刚刚开始使用 Node.js 并尝试使用模块。我已经安装了 Node 和 npm,并确保一切顺利。我将在下面添加代码来向您展示我得到了什么。 我有两个 js 文件,它们在这里。 app.js: va
在 Android 4.4.2 KitKat (API 19) 模拟器上运行时,我的代码出现问题... 当我在 Android 4.3 (API 18) 模拟器上模拟我的项目时,它正常工作并使用 Ma
function more(){ var MoreDetails = document.getElementById('MoreDetails'); More
我正在练习 Javascript,并且有以下代码,该代码在 sets[i][j] = initial_sets [i ][j]; 行。这个想法似乎是正确的,但我不明白为什么会出现错误。 var set
$(document).ready(function(){ $('#name').val('Name1'); }); function clickMe(){ console.lo
我正在创建一个网络应用程序,但我遇到了一个无法解决的简单问题。我已将产生问题的代码放在这里:http://jsfiddle.net/rkumarnirmal/5w3FG/ 应该显示此答案的第二个ale
我正在执行一项长时间运行的任务,在中间的某个位置,可能会抛出此异常: Uncaught DOMException: Blocked a frame with origin "http://localh
我试图通过使用 HTML5 中的 onEnded 属性一首接一首地播放 3 首歌曲。这是我的第一次尝试,但出现错误。 错误: Uncaught ReferenceError: src is not d
检查 Fiddle 以查看发生的故障。 当我将数据(即使我将其留空)添加到文本框并尝试单击“添加”时,它没有执行任何操作。 打开 Chrome 和 Firefox 控制台都给我同样的错误,它说“cha
这个问题在这里已经有了答案: How to access the correct `this` inside a callback (13 个回答) 关闭5年前。 您好,这是我的(快捷方式)示例代码:
我正在处理一个项目,每次 Node 运行我的代码时,浏览器控制台都会给我这个: Uncaught TypeError: Failed to resolve module specifier "expr
我是一名优秀的程序员,十分优秀!