2015-08-19 95 views
0

我有Android後臺服務與我的RabbitMQ服務器連接。我的後臺服務監聽傳入的rabbitmq消息。一切正常,但屏幕熄滅時出現問題。當手機屏幕熄滅時,我的android客戶端斷開連接。我應該怎麼做才能始終與我的android rabbitmq客戶端和rabbitmq服務器連接?Android後臺服務和喚醒鎖

我的代碼都低於:

public class RabbitmqPushService extends Service{ 

private Thread subscribeThread; 
private ConnectionFactory factory; 
private Connection connectionSubscribe; 
private Channel channelSubscribe; 

private NotificationManager mNotificationManager; 
public static int NOTIFICATION_ID = 0; 

private static final String HOST_NAME = Constant.HOST_NAME; //Rabbitmq Host Name 
private static final int PORT_ADDRESS = 5672; 

private static final String EXCHANGE_NAME = "fanout_msg"; 
private static String QUEUE_NAME = Constant.phone_number+"_queue"; //Queue Name 
private static String[] ROUTE_KEY = {"all", Constant.phone_number}; 


@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 


@Override 
public void onCreate() { 
    NOTIFICATION_ID = 0; 
    setupConnectionFactory(); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    if(connectionSubscribe != null) 
    { 
     if(!connectionSubscribe.isOpen()) 
     { 
      connect(); 
     } 
    } 
    else 
    { 
     connect(); 
    } 

    return Service.START_STICKY; 
} 

@Override 
public void onDestroy() { 

    if(connectionSubscribe != null) 
    { 
     disconnectSubscribe(); 
    } 

    NOTIFICATION_ID = 0; 
} 


private void setupConnectionFactory() { 
    factory = new ConnectionFactory(); 
    factory.setHost(HOST_NAME); 
    factory.setPort(PORT_ADDRESS); 
    factory.setUsername(Constant.USERNAME); 
    factory.setPassword(Constant.PASSWORD); 
    factory.setRequestedHeartbeat(60); 
} 

private void connect() 
{ 
    final Handler incomingMessageHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      String message = msg.getData().getString("msg"); 
      try { 
       JSONObject jsonObject = new JSONObject(message); 
       BeepHelper.msgBeep(getApplicationContext()); 
       sendNotification("From : " + jsonObject.getString("from"), jsonObject.getString("message")); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    subscribe(incomingMessageHandler); 
    publishToAMQP(); 
} 

private void disconnectSubscribe() 
{ 
    subscribeThread.interrupt(); 

    try { 
     channelSubscribe.close(); 
     connectionSubscribe.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    catch (TimeoutException e) { 
     e.printStackTrace(); 
    } 
} 

void subscribe(final Handler handler) 
{ 
    subscribeThread = new Thread() 
    { 
     @Override 
     public void run() { 
      while(true) { 
       try { 
        connectionSubscribe = factory.newConnection(); 

        channelSubscribe = connectionSubscribe.createChannel(); 

        channelSubscribe.exchangeDeclare(EXCHANGE_NAME, "fanout"); 

        channelSubscribe.queueDeclare(QUEUE_NAME, true, false, false, null); 


        for(int i = 0; i<ROUTE_KEY.length; i++) 
        { 
         channelSubscribe.queueBind(QUEUE_NAME, EXCHANGE_NAME, ROUTE_KEY[i]); 
        } 

        QueueingConsumer consumer = new QueueingConsumer(channelSubscribe); 

        channelSubscribe.basicConsume(QUEUE_NAME, false, consumer); 

        while (true) { 
         QueueingConsumer.Delivery delivery = consumer.nextDelivery(); 

         String message = new String(delivery.getBody()); 

         Message msg = handler.obtainMessage(); 
         Bundle bundle = new Bundle(); 

         bundle.putString("msg", message); 
         msg.setData(bundle); 
         handler.sendMessage(msg); 

         channelSubscribe.basicAck(delivery.getEnvelope().getDeliveryTag(), false); 

        } 
       } catch (InterruptedException e) { 
        break; 
       } catch (Exception e1) { 
        try { 
         Thread.sleep(4000); //sleep and then try again 
        } catch (InterruptedException e) { 
         break; 
        } 

       } 
      } 
     } 
    }; 
    subscribeThread.start(); 
} 


@Override 
public void publishMessage(String message) { 

    try { 
     queue.putLast(message); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

} 

private void sendNotification(String title, String msg) { 
    mNotificationManager = (NotificationManager) 
      getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); 

    PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, 
      new Intent(getApplicationContext(), MainActivity.class), 0); 

    NotificationCompat.Builder mBuilder = 
      new NotificationCompat.Builder(getApplicationContext()) 
        .setSmallIcon(R.mipmap.ic_launcher) 
        .setContentTitle(title) 
        .setStyle(new NotificationCompat.BigTextStyle() 
          .bigText(msg)) 
        .setContentText(msg); 

    mBuilder.setContentIntent(contentIntent); 
    mNotificationManager.notify(NOTIFICATION_ID++, mBuilder.build()); 
} 

}

+0

您正在啓動粘滯服務。這將確保您的服務在被框架殺死後會重新啓動。但是如果你調用stopSelf(),那麼它會被殺死,並不會再次啓動。在您的具體情況下,我不確定誰在查殺服務。但你可以嘗試的一個選擇是獲得喚醒鎖定。如果你獲得喚醒鎖定,那麼它會阻止框架殺死它。一旦你的交易結束,你可以釋放喚醒鎖,讓它免費的框架來殺死它。 – vicky

+0

這種方法是否奏效? – vicky

回答

0

你需要一個喚醒鎖,以保持手機運行時的屏幕是關閉的。喚醒鎖定允許您的應用程序控制主機設備的電源狀態。

添加WAKE_LOCK允許應用程序的清單文件:

<uses-permission android:name="android.permission.WAKE_LOCK" /> 

然後加入onCreate()如下:

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
wakelock= pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getCanonicalName()); 
wakelock.acquire();