本來是想說在原本的原始碼上面讓他定時反覆啟動。
不過這樣每次都要額外加code以及build code,實在是有點麻煩。
所以這邊試著寫一個簡單的APP去定時做這件事情。
不過Android APP嗎,你知道的,如果用一般的delay的話,過一下就ANR了
爬了一下Android framework的做法,後來決定用Handler thread + delay message的方法來做
概念上是宣告一個handler thread,這東西會用一個獨立的thread去聽message。
如果有人對這個handler 送message,handler可以根據不同的message,去做不同的事情。
而利用延遲訊息(delayMessage),可以達到定時去做同一件事情的效果。
這邊筆記一下Handler底下sendEmptyMessage 和sendEmptyMessageDelayed的差異。
sendEmptyMessage
顧名思義,這個function是送一個空的訊息給Handler
所以不用把東西特別包成Message型態,可以直接送一個int的值
原生宣告是 boolean sendEmptyMessageDelayed (int what, long delayMillis)
sendEmptyMessageDelayed
相較於sendEmptyMessage,他可以決定到底這個message要等多久後再送,單位是ms
下面是一個簡單的範例:
private static final int NEXT_ACTION_INTERVAL_MS = 5000; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "onCreate()+"); setContentView(R.layout.main); context = this; mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); mLock = mWifiManager.createMulticastLock(TAG); mHandler = new Handler(Looper.getMainLooper()) ; // 宣告一個按鈕,按下去後就會去sendEmptyMessage(CMD_START_TEST)給mThreadHandler button1 = (Button) findViewById(R.id.button1); button1.setOnClickListener( new OnClickListener() { public void onClick(View v) { mThreadHandler.sendEmptyMessage(CMD_START_TEST); result_text.setText("Start thread action"); } }); ... mThread = new HandlerThread("name"); mThread.start(); mThreadHandler = new Handler(mThread.getLooper()) { private boolean isRunning = false; private int mCounter = 0; @Override public void handleMessage (Message msg) { super.handleMessage(msg); switch (msg.what) { // ** 接到CMD_START_TEST後,除了做特定的事情外。 // ** 並會等候NEXT_ACTION_INTERVAL_MS後再發CMD_LOOP_TEST case CMD_START_TEST: if (!isRunning) { this.sendEmptyMessageDelayed(CMD_LOOP_TEST, NEXT_ACTION_INTERVAL_MS); isRunning = true; Log.e(TAG, "Start Testing!"); mWifiManager.startScan(); mCounter++; result_text.setText("Repeat times: " + mCounter); } break; case CMD_STOP_TEST: isRunning = false; mCounter = 0; break; // ** 接到CME_LOOP_TEST後,繼續相同的測試&準備下一個NEXT_ACTION_INTERVAL_MS後的message case CMD_LOOP_TEST: if (isRunning) { mWifiManager.startScan(); mCounter++; result_text.setText("Repeat times: " + mCounter); this.sendEmptyMessageDelayed(CMD_LOOP_TEST, NEXT_ACTION_INTERVAL_MS); } break; } } };
沒有留言:
張貼留言