java保留MQTT主题在恢复活动时订阅
我有一个MQTT服务类,MyMQTT服务。类,在我登录应用程序时运行:
Intent intent = new Intent(getApplicationContext(), MyMqttService.class);
startService(intent);
然后我有各种各样的活动,在其中一个活动中,我有切换按钮来选择我想要订阅的频道。在onPause/onResume中,我检查哪些按钮处于打开状态,哪些按钮处于关闭状态,并使它们在返回到该活动时处于相同的状态。问题是,如果在我恢复活动时至少有一个按钮处于打开状态,就会出现错误,应用程序崩溃,因为我的应用程序尝试订阅,但无法
我的服务级别:
public class MyMqttService extends Service implements MqttCallback, IMqttActionListener {
private final IBinder binder = new MyBinder();
private MqttAndroidClient mqttClient;
private MqttConnectOptions mqttConnectOptions;
private static final MemoryPersistence persistence = new MemoryPersistence();
private ArrayList<MqttAndroidClient> lostConnectionClients;
private String clientId = "";
private boolean isReady = false;
private boolean doConnectTask = true;
private boolean isConnectInvoked = false;
private Handler handler = new Handler();
private final int RECONNECT_INTERVAL = 10000; // 10 seconds
private final int DISCONNECT_INTERVAL = 20000; // 20 seconds
private final int CONNECTION_TIMEOUT = 60;
private final int KEEP_ALIVE_INTERVAL = 200;
private String broker_url = "xxx.xxx.xxx.xxx";
public class MyBinder extends Binder {
public MyMqttService getService() {
return MyMqttService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
initMqttClient();
}
private void initMqttClient() {
if(mqttClient != null) {
mqttClient = null;
}
lostConnectionClients = new ArrayList<>();
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setConnectionTimeout(CONNECTION_TIMEOUT);
mqttConnectOptions.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
setNewMqttClient();
handler.post(connect);
handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
}
private void setNewMqttClient() {
mqttClient = new MqttAndroidClient(MyMqttService.this, broker_url, clientId, persistence);
mqttClient.setCallback(this);
}
public Runnable connect = new Runnable() {
public void run() {
connectClient();
handler.postDelayed(connect, RECONNECT_INTERVAL);
}
};
public Runnable disconnect = new Runnable() {
public void run() {
disconnectClients();
handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
}
};
private void connectClient() {
if(doConnectTask) {
doConnectTask = false;
try {
isConnectInvoked = true;
mqttClient.connect(mqttConnectOptions, null, this);
} catch (MqttException ex) {
doConnectTask = true;
System.out.println("MQTT exception 1: " + ex.toString());
}
}
}
private void disconnectClients() {
if (lostConnectionClients.size() > 0) {
// Disconnect lost connection clients
for (MqttAndroidClient client : lostConnectionClients) {
if (client.isConnected()) {
try {
client.disconnect();
} catch (MqttException e) {
System.out.println("MQTT exception 2: " + e.toString() );
}
}
}
// Close already disconnected clients
for (int i = lostConnectionClients.size() - 1; i >= 0; i--) {
try {
if (!lostConnectionClients.get(i).isConnected()) {
MqttAndroidClient client = lostConnectionClients.get(i);
client.close();
lostConnectionClients.remove(i);
}
} catch (IndexOutOfBoundsException e) {
System.out.println("MQTT exception 3: " + e.toString());
}
}
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onSuccess(IMqttToken asyncActionToken) {
isReady = true;
// subscribe here
subscribe("");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
setNewMqttClient();
isReady = false;
doConnectTask = true;
isConnectInvoked = false;
}
public void subscribe(String topic) {
try {
mqttClient.subscribe(topic, 0);
isReady = true;
} catch (MqttSecurityException mqttSexEx) {
isReady = false;
} catch (MqttException mqttEx) {
isReady = false;
}
}
private void unsubscribe(String topic) {
try {
mqttClient.unsubscribe(topic);
} catch (MqttSecurityException mqttSecEx) {
System.out.println("MQTT exception 4: " + mqttSecEx.toString());
} catch (MqttException mqttEx) {
System.out.println("MQTT exception 5: " + mqttEx.toString());
}
}
private void publish(String topic, String jsonPayload) {
if(!isReady) {
return;
}
try {
MqttMessage msg = new MqttMessage();
msg.setQos(0);
msg.setPayload(jsonPayload.getBytes("UTF-8"));
mqttClient.publish(topic, msg);
} catch (Exception ex) {
System.out.println("MQTT exception 6: " + ex.toString());
}
}
@Override
public void connectionLost(Throwable cause) {
System.out.println("MQTT exception 7: " + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
// do something
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("MQTT exception 8: deliveryComplete()");
}
}
我使用swich按钮进行的活动,我在其中订阅:
public class DefinicoesActivity extends AppCompatActivity {
private Switch switchSaude;
private Switch switchAlimentacao;
private Switch switchDesporto;
private static Bundle bundle = new Bundle();
private String topico;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_definicoes);
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://5.196.27.244:1883", "users");
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
String titulo = payload.substring(0, payload.indexOf("\n"));
System.out.println("mensagem receitas:" + titulo + " " + topic);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
}
});
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("Connection Success!");
try {
System.out.println("Subscribing to /test");
mqttAndroidClient.subscribe("/test", 0);
System.out.println("Subscribed to /test");
} catch (MqttException ex) {
System.out.println("MQTT Definicoes excpetion: " + ex);
}
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.out.println("MQTT Definicoes excpetion 2:" + exception.toString());
}
});
} catch (MqttException ex) {
System.out.println("MQTT Definicoes excpetion 3:" + ex.toString());
}
switchSaude = findViewById(R.id.switchSaude);
switchAlimentacao = findViewById(R.id.switchAlimentacao);
switchDesporto = findViewById(R.id.switchDesporto);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
setTitle("Definiçoes");
switchAlimentacao.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton View, boolean isChecked) {
if(!isChecked){
Snackbar.make(View, "Cancelou a subscrição de dicas sobre Receitas", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
else
{
topico = "Receitas";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
Snackbar.make(View, "Sobscreveu dicas sobre Receitas", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
}
});
switchDesporto.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton View, boolean isChecked) {
if(!isChecked){
Snackbar.make(View, "Cancelou a subscrição de dicas sobre Desporto", Snackbar.LENGTH_LONG).show();
}
else
{
topico = "Desporto";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
Snackbar.make(View, "Sobscreveu dicas sobre Desporto", Snackbar.LENGTH_LONG).show();
}
}
});
switchSaude.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton View, boolean isChecked) {
if(!isChecked){
Snackbar.make(View, "Cancelou a subscrição de dicas sobre Saúde", Snackbar.LENGTH_LONG).show();
}
else
{
topico = "Saúde";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
Snackbar.make(View, "Sobscreveu dicas sobre Saúde", Snackbar.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onPause() {
super.onPause();
bundle.putBoolean("switchAlimentacaoState", switchAlimentacao.isChecked());
bundle.putBoolean("switchDesportoState", switchDesporto.isChecked());
bundle.putBoolean("switchSaudeState", switchSaude.isChecked());
}
@Override
protected void onResume() {
super.onResume();
final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://5.196.27.244:1883", "users");
if(bundle.getBoolean("switchAlimentacaoState")){
switchAlimentacao.setChecked(bundle.getBoolean("switchAlimentacaoState"));
topico = "Receitas";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
}
if(bundle.getBoolean("switchDesportoState")){
switchDesporto.setChecked(bundle.getBoolean("switchDesportoState"));
topico = "Desporto";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
}
if(bundle.getBoolean("switchSaudeState")){
switchDesporto.setChecked(bundle.getBoolean("switchSaudeState"));
topico = "Saúde";
try {
mqttAndroidClient.subscribe(topico, 1);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
}
我的错误:
12-27 12:06:30.264 20361-20361/com.support.安卓.iplfit E/AndroidRuntime: FATAL EXCEPTION: main Process: com.support.安卓.iplfit, PID: 20361 java.lang.RuntimeException: Unable to resume activity {com.support.安卓.iplfit/com.support.安卓.iplfit.Activities.DefinicoesActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.eclipse.paho.安卓.service.MqttService.subscribe(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)' on a null object reference at 安卓.app.ActivityThread.performResumeActivity(ActivityThread.java:3400) at 安卓.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440) at 安卓.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713) at 安卓.app.ActivityThread.-wrap12(ActivityThread.java) at 安卓.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) at 安卓.os.Handler.dispatchMessage(Handler.java:102) at 安卓.os.Looper.loop(Looper.java:154) at 安卓.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:756) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void org.eclipse.paho.安卓.service.MqttService.subscribe(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)' on a null object reference at org.eclipse.paho.安卓.service.MqttAndroidClient.subscribe(MqttAndroidClient.java:906) at org.eclipse.paho.安卓.service.MqttAndroidClient.subscribe(MqttAndroidClient.java:841) at com.support.安卓.iplfit.Activities.DefinicoesActivity$3.onCheckedChanged(DefinicoesActivity.java:122) at 安卓.widget.CompoundButton.setChecked(CompoundButton.java:156) at 安卓.widget.Switch.setChecked(Switch.java:1074) at com.support.安卓.iplfit.Activities.DefinicoesActivity.onResume(DefinicoesActivity.java:213) at 安卓.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269) at 安卓.app.Activity.performResume(Activity.java:6766) at 安卓.app.ActivityThread.performResumeActivity(ActivityThread.java:3377) at 安卓.app.ActivityThread.handleResumeActivity(ActivityThread.java:3440) at 安卓.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713) at 安卓.app.ActivityThread.-wrap12(ActivityThread.java) at 安卓.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) at 安卓.os.Handler.dispatchMessage(Handler.java:102) at 安卓.os.Looper.loop(Looper.java:154) at 安卓.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.安卓.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) at com.安卓.internal.os.ZygoteInit.main(ZygoteInit.java:756)
共 (0) 个答案