java Timer計時器在android中運行時出現的問題

來源:互聯網
上載者:User

目標: 希望採用Timer來計時,要求在服務中運行,每10分鐘記錄一次資料。但是採用timer來做了以後,發現統計的次數沒有達到預期的目標。甚至沒有運行,以下是在測試情況

1.為了能夠看到測試效果,將迴圈時間設定為2秒

本打算用服務做測試,但為了方便就用activity做測試

package com.test.timertest;/** * 對計時器的測試 */import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.TextView;public class TimerActivity extends Activity {private TextView txtCount;private int count;//處理介面private  Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {if(msg.arg1 == 1){txtCount.setText(String.valueOf(count));}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.txtCount = (TextView)findViewById(R.id.count);new Timer().schedule(countTask, 10, 2000);  //延遲10毫秒,每2秒鐘執行一次     }//任務TimerTask countTask = new TimerTask() {@Overridepublic void run() {// TODO Auto-generated method stubcount ++;Message msg = new Message();msg.arg1 = 1;handler.sendMessage(msg);}};}

結果:

1.將手機與電腦串連測試,改程式正常,能夠一直運行。並且按下電源鍵後仍然能夠正常運行,統計的次數也正常

2.手機與電腦中斷連線後,然後重新運行改程式,該程式能正常運行。然後按下電源鍵,手機處於待機狀態,過一段時間後在看螢幕上的次數,發現次數沒有動,不知道為啥???

3.手機與電腦中斷連線後,運行程式,然後按home鍵,在手機沒有處於待機的狀態下,統計的次數發生變化,能夠正常運行。但是如果手機處於待機狀態後,程式不在運行。

問題: 手機待機後會讓大部分程式不在運行(除電話,簡訊等)。難道這是系統的保護機制???  

2.採用線程的Sleep處理;

package com.test.timertest;/** * 對計時器的測試 */import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.TextView;public class TimerActivity extends Activity {private TextView txtCount;private int count;//處理介面private  Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {if(msg.arg1 == 1){txtCount.setText(String.valueOf(count));}};};@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.txtCount = (TextView)findViewById(R.id.count);//new Timer().schedule(countTask, 10, 2000);  //延遲10毫秒,每2秒鐘執行一次     new CountThread().start();}class CountThread extends Thread{@Overridepublic void run() {while(true){count ++;Message msg = new Message();msg.arg1 = 1;handler.sendMessage(msg);try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}////任務//TimerTask countTask = new TimerTask() {////@Override//public void run() {//// TODO Auto-generated method stub//count ++;//Message msg = new Message();//msg.arg1 = 1;//handler.sendMessage(msg);//}//};}

採用Sleep的處理結果和上面1中的一樣,懷疑是不是activity和thread有區別,於是採用線程來處理,並將結果儲存到xml中

服務如下:

package com.test.timertest;import java.util.Timer;import java.util.TimerTask;import android.app.Service;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.os.IBinder;public class CountService extends Service {@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();new Timer().schedule(countTask, 10, 2000);   //2秒鐘}// 任務TimerTask countTask = new TimerTask() {@Overridepublic void run() {saveAppCount();}};// 儲存資料private void saveAppCount() {int count = getAppCount() + 1;SharedPreferences sf = getSharedPreferences("appcount",Context.MODE_PRIVATE);Editor editor = sf.edit();editor.putInt("count", count);editor.commit();}// 擷取資料public int getAppCount() {SharedPreferences spf = getSharedPreferences("appcount",Context.MODE_PRIVATE);return spf.getInt("count", 0);}}

顯示資料的activity

package com.test.timertest;/** * 對計時器的測試 */import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.os.Bundle;import android.widget.TextView;public class TimerActivity extends Activity {private TextView txtCount;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.txtCount = (TextView)findViewById(R.id.count);SharedPreferences spf = getSharedPreferences("appcount",Context.MODE_PRIVATE);int count =  spf.getInt("count", 0);txtCount.setText(String.valueOf(count));Intent intent = new Intent(this,CountService.class);startService(intent);}}

測試結果::

1.手機和電腦串連,手機處於偵錯模式,不管是按下電源鍵讓手機處於待機狀態還是按下home鍵,服務都能夠正常的統計資料

2.手機與電腦中斷連線,不管是手機自動處於待機狀態還是主動按下電源鍵讓手機處於待機狀態,服務裡面的線程都沒有正常的記錄資料。 求解 ???

最終結合網上資料採用AlarmManager 控制計時操作,能夠保證系統在sleep的時候發出廣播,達到統計的目的

package com.test.timertest;/** * 對計時器的測試 */import java.util.Timer;import android.app.Activity;import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.os.Bundle;import android.os.SystemClock;import android.widget.TextView;public class TimerActivity extends Activity {private TextView txtCount;public final String ACTION = "com.test.timertest.alarmreciver";@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.txtCount = (TextView)findViewById(R.id.count);SharedPreferences spf = getSharedPreferences("appcount",Context.MODE_PRIVATE);int count =  spf.getInt("count", 0);txtCount.setText(String.valueOf(count));//Intent intent = new Intent(this,CountService.class);//startService(intent);//鬧鐘全域變數AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);Intent intent = new Intent(ACTION);PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);long firsttime = SystemClock.elapsedRealtime();firsttime  += 2*1000;am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,firsttime, 2*1000,sender);  //AlarmManager.ELAPSED_REALTIME_WAKEUP 這裡要用這個類型的tiype才能保證系統在sleep的時候也能發廣播,不懂的可以去看文檔的介紹}}

接受廣播的類

package com.test.timertest;import android.content.BroadcastReceiver;import android.content.Context;import android.content.Intent;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;public class AlarmReciver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stubsaveAppCount(context);}// 儲存資料private void saveAppCount(Context context) {int count = getAppCount(context) + 1;SharedPreferences sf = context.getSharedPreferences("appcount",Context.MODE_PRIVATE);Editor editor = sf.edit();editor.putInt("count", count);editor.commit();}// 擷取資料public int getAppCount(Context context) {SharedPreferences spf = context.getSharedPreferences("appcount",Context.MODE_PRIVATE);return spf.getInt("count", 0);}}




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.