我有一个MQTT服务类,MyMqttService.class,乳宁当我登录在我的应用程序:
Intent intent = new Intent(getApplicationContext(), MyMqttService.class);
startService(intent);
然后,我有各种各样的活动,并在其中的一个,我有开关按钮,选择我要订阅的频道。 在我的onPause /的onResume,我检查哪些按钮上的开关状态,让他们去到相同的状态,当我回来的那个活动。 问题是,如果有,当我恢复活动,我得到一个错误,我aplication崩溃的至少一个按钮,因为我的应用程序试图以认购,和着。
我的服务类:
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日:06:30.264 20361-20361 / com.support.android.iplfit E / AndroidRuntime:致命异常:主要过程:com.support.android.iplfit,PID:20361了java.lang.RuntimeException:无法恢复活动{com.support.android.iplfit / com.support.android.iplfit.Activities.DefinicoesActivity}:显示java.lang.NullPointerException:尝试调用虚拟方法“无效org.eclipse.paho.android.service.MqttService.subscribe(java的.lang.String,java.lang.String中,INT,java.lang.String中,java.lang.String中)”上在android.app在android.app.ActivityThread.performResumeActivity(ActivityThread.java:3400空对象引用) .ActivityThread.handleResumeActivity(ActivityThread.java:3440)在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)在android.app.ActivityThread.-wrap12(ActivityThread.java)在android.app.ActivityThread $ H.handleMessage (ActivityThread.java:1460)在android.os.Handler.dispatchMessage(Handler.java:102)在android.os.Looper.loop(Looper.java:154)在android.app.Activ ityThread.main(ActivityThread.java:6077)在java.lang.reflect.Method.invoke(本机方法)在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:866)在com.android。 internal.os.ZygoteInit.main(ZygoteInit.java:756)产生的原因:显示java.lang.NullPointerException:尝试调用虚拟方法“无效org.eclipse.paho.android.service.MqttService.subscribe(java.lang.String中, java.lang.String中,INT,java.lang.String中,java.lang.String中)”上在组织在org.eclipse.paho.android.service.MqttAndroidClient.subscribe(MqttAndroidClient.java:906空对象引用)。 eclipse.paho.android.service.MqttAndroidClient.subscribe(MqttAndroidClient.java:841)在com.support.android.iplfit.Activities.DefinicoesActivity $ 3.onCheckedChanged(DefinicoesActivity.java:122)在android.widget.CompoundButton.setChecked(CompoundButton的.java:156)在android.widget.Switch.setChecked(Switch.java:1074)在com.support.android.iplfit.Activities.DefinicoesActivity.onResume(DefinicoesActivity.java:213)在安德烈 oid.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269)在android.app.Activity.performResume(Activity.java:6766)在android.app.ActivityThread.performResumeActivity(ActivityThread.java:3377)在android.app.ActivityThread .handleResumeActivity(ActivityThread.java:3440)在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)维持在android.app.ActivityThread $ H.handleMessage android.app.ActivityThread.-wrap12(ActivityThread.java)(ActivityThread的.java:1460)在android.os.Handler.dispatchMessage(Handler.java:102)在android.os.Looper.loop(Looper.java:154)在android.app.ActivityThread.main(ActivityThread.java:6077)在java.lang.reflect.Method.invoke(本机方法)在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:866)在com.android.internal.os.ZygoteInit.main(ZygoteInit。 Java的:756)