如何使用 Firebase JobDispatcher 进行 nv-websocket-client 的异步重连?
How to use Firebase JobDispatcher for async reconnection of nv-websocket-client?
在 Android 应用程序中(使用 minSdkVersion 16
)我使用 nv-websocket-client 库:
public class MainActivity extends AppCompatActivity {
private WebSocket mWs;
private WebSocketFactory mWsFactory = new WebSocketFactory();
private WebSocketListener mWsListener = new WebSocketAdapter() {
@Override
public void onConnected(WebSocket ws, Map<String, List<String>> headers) throws Exception {
mReconnectDispatcher.cancelAll();
}
// connection on the background thread has failed (onDisconnected will not be called!)
@Override
public void onConnectError(WebSocket ws, WebSocketException ex) throws Exception {
reconnect();
}
@Override
public void onDisconnected(WebSocket ws,
WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame,
boolean closedByServer) throws Exception {
reconnect();
}
@Override
public void onTextMessage(WebSocket ws, String str) throws Exception {
// here the WebSockets communication happens
}
};
@Override
public void onResume() {
super.onResume();
reconnect();
}
@Override
public void onPause() {
super.onPause();
if (mWs != null) {
mWs.disconnect();
}
}
和Firebase JobDispatcher(版本0.8.4)用于重新连接WebSocket:
private FirebaseJobDispatcher mReconnectDispatcher;
public class ReconnectService extends JobService {
@Override
public boolean onStartJob(JobParameters job) {
try {
mWs = mWsFactory.createSocket("ws://demos.kaazing.com/echo");
mWs.addListener(mWsListener);
mWs.connectAsynchronously(); // uses background thread
} catch (Exception ex) {
Log.w(TAG, "Can not create WebSocket connection", ex);
}
return true; // Answers the question: "Is there still work going on?"
}
@Override
public boolean onStopJob(JobParameters job) {
return false; // Answers the question: "Should this job be retried?"
}
}
private void reconnect() {
Job myJob = mReconnectDispatcher.newJobBuilder()
.setService(ReconnectService.class)
.setTag(ReconnectService.class.getSimpleName())
.setRecurring(false)
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
.setTrigger(Trigger.executionWindow(0, 60))
.setReplaceCurrent(true)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build();
mReconnectDispatcher.mustSchedule(myJob);
}
在 AndroidManifest.xml 我有:
<service
android:name=".MainActivity$ReconnectService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
不幸的是,我在 60 秒后收到运行时错误:
16998-16998/de.slova E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.slova, PID: 16998
java.lang.RuntimeException: Unable to instantiate service de.slova.MainActivity$ReconnectService: java.lang.InstantiationException: java.lang.Class<de.slova.MainActivity$ReconnectService> has no zero argument constructor
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3389)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.InstantiationException: java.lang.Class<de.slova.MainActivity$ReconnectService> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3386)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
1472-1487/? I/ActivityManager: Showing crash dialog for package de.slova u0
我已尝试将默认构造函数添加到我的 class,但错误仍然存在:
public class ReconnectService extends JobService {
public ReconnectService() {
}
有没有人知道这里有什么问题?
我也已将我的问题提交为 issue #189。
将 ReconnectService
放在它自己的 class 中(而不是内部 class 到 MainActivity
)。或者,尝试使内部 class static
.
非静态内部 classes 在 Java 中的工作方式是它们只能由外部 class 的实例实例化。这就是允许内部 class 的实例访问外部 class 的成员的原因。因此,当 Android 试图创建内部 class 的实例时,它不能这样做,因为它不知道外部 class 的哪个实例应该是它的一部分的。错误信息有点误导。
在 Android 应用程序中(使用 minSdkVersion 16
)我使用 nv-websocket-client 库:
public class MainActivity extends AppCompatActivity {
private WebSocket mWs;
private WebSocketFactory mWsFactory = new WebSocketFactory();
private WebSocketListener mWsListener = new WebSocketAdapter() {
@Override
public void onConnected(WebSocket ws, Map<String, List<String>> headers) throws Exception {
mReconnectDispatcher.cancelAll();
}
// connection on the background thread has failed (onDisconnected will not be called!)
@Override
public void onConnectError(WebSocket ws, WebSocketException ex) throws Exception {
reconnect();
}
@Override
public void onDisconnected(WebSocket ws,
WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame,
boolean closedByServer) throws Exception {
reconnect();
}
@Override
public void onTextMessage(WebSocket ws, String str) throws Exception {
// here the WebSockets communication happens
}
};
@Override
public void onResume() {
super.onResume();
reconnect();
}
@Override
public void onPause() {
super.onPause();
if (mWs != null) {
mWs.disconnect();
}
}
和Firebase JobDispatcher(版本0.8.4)用于重新连接WebSocket:
private FirebaseJobDispatcher mReconnectDispatcher;
public class ReconnectService extends JobService {
@Override
public boolean onStartJob(JobParameters job) {
try {
mWs = mWsFactory.createSocket("ws://demos.kaazing.com/echo");
mWs.addListener(mWsListener);
mWs.connectAsynchronously(); // uses background thread
} catch (Exception ex) {
Log.w(TAG, "Can not create WebSocket connection", ex);
}
return true; // Answers the question: "Is there still work going on?"
}
@Override
public boolean onStopJob(JobParameters job) {
return false; // Answers the question: "Should this job be retried?"
}
}
private void reconnect() {
Job myJob = mReconnectDispatcher.newJobBuilder()
.setService(ReconnectService.class)
.setTag(ReconnectService.class.getSimpleName())
.setRecurring(false)
.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
.setTrigger(Trigger.executionWindow(0, 60))
.setReplaceCurrent(true)
.setConstraints(Constraint.ON_ANY_NETWORK)
.build();
mReconnectDispatcher.mustSchedule(myJob);
}
在 AndroidManifest.xml 我有:
<service
android:name=".MainActivity$ReconnectService"
android:exported="false">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
不幸的是,我在 60 秒后收到运行时错误:
16998-16998/de.slova E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.slova, PID: 16998
java.lang.RuntimeException: Unable to instantiate service de.slova.MainActivity$ReconnectService: java.lang.InstantiationException: java.lang.Class<de.slova.MainActivity$ReconnectService> has no zero argument constructor
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3389)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.InstantiationException: java.lang.Class<de.slova.MainActivity$ReconnectService> has no zero argument constructor
at java.lang.Class.newInstance(Native Method)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3386)
at android.app.ActivityThread.-wrap4(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1683)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
1472-1487/? I/ActivityManager: Showing crash dialog for package de.slova u0
我已尝试将默认构造函数添加到我的 class,但错误仍然存在:
public class ReconnectService extends JobService {
public ReconnectService() {
}
有没有人知道这里有什么问题?
我也已将我的问题提交为 issue #189。
将 ReconnectService
放在它自己的 class 中(而不是内部 class 到 MainActivity
)。或者,尝试使内部 class static
.
非静态内部 classes 在 Java 中的工作方式是它们只能由外部 class 的实例实例化。这就是允许内部 class 的实例访问外部 class 的成员的原因。因此,当 Android 试图创建内部 class 的实例时,它不能这样做,因为它不知道外部 class 的哪个实例应该是它的一部分的。错误信息有点误导。