在服务中使用处理程序和线程,Thread.sleep使程序挂起?

时间:2011-06-02 06:20:34

标签: android

我正在处理任务调度程序应用程序作为我的大学项目,我有一项服务来检查任务的到期时间。我已经实现了处理程序来检查过期时间。当应用程序的到期时间与当前时间匹配时,它会发送状态栏通知。此时我使用Thread.sleep方法暂停Thread一分钟,这导致我的应用程序挂起。在logcat中,它显示应用程序占用大量CPU。

我从数据库中获取数据,但是在未调用Thread.sleep时它可以正常工作。 请帮忙。

以下是代码:

package com.apps.niit.taskm;
import java.util.ArrayList;
import java.util.Calendar;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;


public class ExpireTimeService extends Service {

    DataHelper dh;
    ArrayList<String> tData=new ArrayList<String>();
    String date;
    Calendar c;
    String str;
    String str1;
    String str2;
    String str3;
    String str4;
    String str5;
    int notificationID=1;
    String [][] data;
    NotificationManager notificationManager;
    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public void onCreate(){
        super.onCreate();
        dh = new DataHelper(this);
        fetchData();
        handler.removeCallbacks(updateTimeTask);
        handler.postDelayed(updateTimeTask, 1000);  
    }
    public void fetchData(){
        String eDate = android.text.format.DateFormat.format("d/M/yyyy", new java.util.Date()).toString();
        tData.addAll(this.dh.selectDate(eDate));
        data =new String[tData.size()][4];
        if(!tData.isEmpty()){
            for(int i=0; i<tData.size();i++){
                breakString(tData.get(i));
                data[i][0]=str1;
                data[i][1]=str2;
                data[i][2]=str3;
                data[i][3]=str4;
            }
        }
    }

    public void stopService(){
        stopSelf();
    }
    private Runnable updateTimeTask = new Runnable() {
        public void run(){
            try {
                String time = android.text.format.DateFormat.format("k:m", new java.util.Date()).toString();

                for(int i=0; i<tData.size();i++){
                    if(data[i][3].equals(time)){
                    //send notification code goes here
                        String serName = Context.NOTIFICATION_SERVICE;
                        notificationManager = (NotificationManager)getSystemService(serName);               
                        String ticker= data[i][0]+" "+data[i][1]+" "+data[i][2]+" "+data[i][3];
                        long when= System.currentTimeMillis();
                        int icon = R.drawable.icon;
                        Notification notification = new Notification(icon, ticker,when);
                        Intent intent = new Intent (getApplicationContext(), DisplayTask.class);
                        Bundle myBundle = new Bundle();     
                        myBundle.putString("str1", data[i][0]);
                        myBundle.putString("str2", data[i][1]);Log.i("data1",data[i][1]);
                        myBundle.putString("str3", data[i][2]);Log.i("data1",data[i][2]);
                        myBundle.putString("str4", data[i][3]);Log.i("data1",data[i][3]);
                        intent.putExtras(myBundle);
                        PendingIntent launchIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
                        notification.setLatestEventInfo(getApplicationContext(), "", "", launchIntent);
                        notificationID=1;
                        notificationManager.notify(notificationID, notification);
                        Thread.sleep(10000);                    
                    }
                }
                handler.postDelayed(this, 1000);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Log.e("Error from service", e.toString());
            }
        }       
    };

    private void breakString(String str) {
        // TODO Auto-generated method stub
        str1 = str.substring(0, str.indexOf(";"));
        str = str.substring(str1.length()+1, str.length());
        str2 = str.substring(0, str.indexOf(";"));
        str = str.substring(str2.length()+1, str.length());
        str3 = str.substring(0, str.indexOf(";"));
        str4 = str.substring(str3.length()+1, str.length());
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (handler != null)
            handler.removeCallbacks(updateTimeTask);
        handler = null;
    }
    private Handler handler = new Handler();
}

1 个答案:

答案 0 :(得分:2)

当您使用Handler的{​​{1}}功能时,会发生以下情况:

  1. 处理程序将您的postDelayed放入当前线程的Looper队列。
  2. 到时候,Runnable中的代码在UI线程上运行
  3. 请注意,Runnable并不总是将Handler放入UI线程队列。它将Runnable置于当前线程的队列中,并且您当前的线程是UI线程。

    因此,如果您在Runnable中放置Thread.sleep或任何耗费时间(例如网络通信),它将挂起整个UI线程。

    在您的情况下,您应该使用updateTimeTask,请参阅ScheduledExecutorService功能。或者作为替代方案,您可以从scheduleWithFixedDelay函数启动AsyncTask,并在updateTimeTask函数中执行所有繁重工作和Thread.sleep