2

我正在開發應用程序,它將根據生日日期自動發送生日祝福,並由希望者註冊。 我已經創建了一個無限for循環的線程,它將從數據庫獲取當天日期的記錄,自動發送每分鐘的消息。如何在後臺服務中放置線程和無限foor循環

我的代碼在正常活動中正常運行。我想放置在SERVICE.so內部,以幫助我如何放置此代碼並在應用程序啓動時調用服務。

這是我的代碼

// function to run thread 
void startThread() 
{ 
     Thread th=new Thread(){ 
      @Override 
      public void run(){ 
       // 
       try 
       { 
        for (;;) 
        { 
           runOnUiThread(new Runnable() { 
           @Override 
           public void run() { 
            try { 
             //Getting the system date          
             Calendar today=new GregorianCalendar();     
             SimpleDateFormat simdate=new SimpleDateFormat("yyyy-MM-dd");            
             SimpleDateFormat timeFormat=new SimpleDateFormat("hh:mm a");          
             String systemDate=simdate.format(today.getTime()); 
             String systemTime=timeFormat.format(today.getTime()); 

             // system process 

             minText.setText(systemTime); 

             control.open(); 
             ArrayList<UserPOJO> event=control.MyDatabaseRecords(systemDate);//get the records for system date 
             for(int i=0;i<event.size();i++) 
             { 
              String dbContactID=event.get(i).getContactID(); 
              String dbContactNumber=event.get(i).getContactNumber(); 
              String dbContactMessage=event.get(i).getContactMessageBody(); 
              String dbDate=event.get(i).getContactWishDate();  
              String dbTime=event.get(i).getContactWishTime();  


              String[] time=dbTime.split("[ \\:]"); 
              String myhr=time[0]; 
              String mymin=time[1]; 
              String aorp=time[2]; 
              String myDBhr=addZeroBeforeDate(myhr); 
                   // adding zero before time hour 
              String CurrentDBTime=myDBhr+":"+mymin+" "+aorp; 



              Toast.makeText(getApplicationContext(),"Searching.....", 300).show(); 

              //Toast.makeText(getApplicationContext(),"DB Time:"+CurrentDBTime+"System Time"+systemTime, 300).show(); 


              if((dbDate.equals(systemDate))&& (CurrentDBTime.equals(systemTime))) 
              {// 
               System.out.println("Message Send at:"+systemTime); 
               Toast.makeText(getApplicationContext(),"Message Sent to :"+dbContactNumber+"on System time:"+systemTime, 300).show(); 
               sendSMS(dbContactNumber, dbContactMessage);     

               //send.sendSMS(dbContactNumber, dbContactMessage); 
              } 
            } 

            } 
            catch(Exception e) 
            { 
             e.printStackTrace(); 
            } 
           } 
           }); 
           Thread.sleep(60000); 
           // Thread.sleep(20000); 
        // set the scan for 60 seconds 
        } 
       } 
       catch (InterruptedException e) { 
       } 

      } // run 
     }; 
    th.start(); 
} 

    // Add zero if it is 

    dateval<10 
    private static String addZeroBeforeDate(String datevalue) 
    { 
     String dval=datevalue; 

     for(int i=dval.length();i<2;i++) 
     { 
      dval="0"+dval; 
     } 

     return dval; 
    } 
+0

使用AlarmManager不要在永久for循環中每分鐘查詢數據庫。用戶的電池完全耗盡不會很長時間。 – Boardy

回答

1

首先有一個名爲Timer在Java類,使用它..不要寫無窮無盡,在線程中運行循環,也就是做事情的一個非常棘手的方式並可能導致所有類型的問題。

這裏我有一個TimerService實施。您可以嘗試使用此代碼開始。我建議你也看看android Alarm類。

public class SomeService extends Service { 
    private static final String TAG = SomeService.class.getSimpleName(); 
    private static final long UPDATE_INTERVAL = 1 * 15 * 1000; 
    private static final long DELAY_INTERVAL = 0; 

    private Timer timer; 

    public SomeService() { 
    } 

    public void onCreate() { 
     Log.d(TAG, "STARTING SERVICE"); 

     super.onCreate(); 

    } 

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

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

     timer.scheduleAtFixedRate(
        new TimerTask() { 
         public void run() { 
          //DO YOUR CODE 
         } 
        }, 
        DELAY_INTERVAL, 
        UPDATE_INTERVAL 
      ); 

     super.onStartCommand(intent, flags, startId); 

     return 0; 
    } 

    @Override 
    public void onDestroy() { 
     timer.cancel(); 

     super.onDestroy(); 
    } 
} 

您可以通過Service從您的出發Activity

調用此startService(new Intent(this, NotificationService.class));而且看thisthis鏈接,瞭解更多信息開始。

+1

感謝Neil的迴應,但是如果我將代碼替換爲您的代碼,我的應用程序會自動關閉。如果我將應用程序置於空線程中,我的應用程序無法打開將會出現問題。 –

+0

你得到了什麼錯誤? – Neil

+1

不幸的是,應用程序已停止 –

3

您應該使用IntentServiceAlarmManager調用定期服務:

IntentService的onHandleIntent()方法被調用在不同的線程,所以你不必擔心阻止用戶界面。

AlarmManager也應該比TimerTask更有效率。 (見Timer Task VS Alarm Manager usage in Android Service

public class MyService extends IntentService { 

    private AlarmManager alarmManager; 

    private boolean started; 
    private PendingIntent pendingIntent; 

    public MyService() { 
     super(MyService.class.getSimpleName()); 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     if (! started) { 
      started = true; 

      // Call the service periodically every 15 minutes 
      pendingIntent = PendingIntent.getService(
        getApplicationContext(), 
        0, 
        intent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 

      alarmManager.setRepeating(
        AlarmManager.ELAPSED_REALTIME, 
        AlarmManager.INTERVAL_FIFTEEN_MINUTES, 
        AlarmManager.INTERVAL_FIFTEEN_MINUTES, 
        pendingIntent); 
     } 

     // DO YOUR STUFF HERE 
    } 
} 

看一看的AlarmManager documention你可以使用的選項。

+0

當我在構造函數中分配'alarmManager'因爲它在另一個線程上運行,所以我在'getApplicationContext'上得到空指針。你能改善你的答案嗎? – Iero

+0

事實上,AlarmManager應該在onCreate()方法中初始化。我會相應地更新我的答案 – nicopico

+0

請在我當前的工作中使用您的答案:D – Iero