在服务处理器和线程工作,使视频下载挂程序? [英] Working with handlers and threads in service, Thread.sleep makes the program to hang?

查看:108
本文介绍了在服务处理器和线程工作,使视频下载挂程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个任务调度程序为我的大学项目,我有一个检查任务的到期时间的服务。我已实施处理程序来检查过期时间。当应用程序的到期时间与当前的时间相匹配,然后它发送一个状态栏通知。在这一点上,我使用了Thread.sleep方法一分钟,这是造成我的应用程序挂起暂停线程。在logcat中它被应用程序显示了沉重的CPU占用率。

我正在从读取数据库中的数据,但它工作正常时,视频下载不叫。
请帮忙。

下面是code:

 包com.apps.niit.taskm;
进口的java.util.ArrayList;
进口的java.util.Calendar;进口android.app.Notification;
进口android.app.NotificationManager;
进口android.app.PendingIntent;
进口android.app.Service;
进口android.content.Context;
进口android.content.Intent;
进口android.os.Bundle;
进口android.os.Handler;
进口android.os.IBinder;
进口android.util.Log;
公共类ExpireTimeService延伸服务{    DataHelper DH;
    ArrayList的<串GT; TDATA =新的ArrayList<串GT;();
    字符串日期;
    日历℃;
    字符串str;
    串STR1;
    字符串STR2;
    串STR3;
    串STR4;
    STR5串;
    INT notificationID = 1;
    的String [] []的数据;
    NotificationManager notificationManager;
    @覆盖
    公众的IBinder onBind(意向为arg0){
        // TODO自动生成方法存根
        返回null;
    }
    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        DH =新DataHelper(本);
        fetchData();
        handler.removeCallbacks(updateTimeTask);
        handler.postDelayed(updateTimeTask,1000);
    }
    公共无效fetchData(){
        字符串EDATE = android.text.format.DateFormat.format(D / M / yyyy,将新java.util.Date())的toString()。
        tData.addAll(this.dh.selectDate(EDATE));
        数据=新的String [tData.size()] [4];
        如果(!tData.isEmpty()){
            的for(int i = 0; I< tData.size();我++){
                breakString(tData.get(I));
                数据[I] [0] = STR1;
                数据[I] [1] = STR2;
                数据[I] [2] = STR3;
                数据[I] [3] = STR4;
            }
        }
    }    公共无效stopService(){
        stopSelf();
    }
    私人Runnable接口updateTimeTask =新的Runnable(){
        公共无效的run(){
            尝试{
                字符串时间= android.text.format.DateFormat.format(K:M,新java.util.Date())的toString();                的for(int i = 0; I< tData.size();我++){
                    如果(数据由[i] [3] .equals(时间)){
                    //发送通知code到这里
                        字符串serName = Context.NOTIFICATION_SERVICE;
                        notificationManager =(NotificationManager)getSystemService(serName);
                        串股票=数据[I] [0] ++数据由[i] [1] ++数据由[i] [2] ++数据由[i] [3];
                        时长= System.currentTimeMillis的();
                        INT图标= R.drawable.icon;
                        通知通知=新的通知(图标,股票,时);
                        意向意图=新意图(getApplicationContext(),DisplayTask.class);
                        捆绑myBundle =新包();
                        myBundle.putString(STR1,数据[I] [0]);
                        myBundle.putString(STR2」,数据[I] [1]); Log.i(DATA1,数据[I] [1]);
                        myBundle.putString(STR3,数据[I] [2]); Log.i(DATA1,数据[I] [2]);
                        myBundle.putString(STR4,数据[I] [3]); Log.i(DATA1,数据[I] [3]);
                        intent.putExtras(myBundle);
                        的PendingIntent launchIntent = PendingIntent.getActivity(getApplicationContext(),0,意向,0);
                        notification.setLatestEventInfo(getApplicationContext(),,,launchIntent);
                        notificationID = 1;
                        notificationManager.notify(notificationID,通知);
                        视频下载(10000);
                    }
                }
                handler.postDelayed(这一点,1000);
            }赶上(例外五){
                // TODO自动生成catch块
                Log.e(从服务中的错误,e.toString());
            }
        }
    };    私人无效breakString(字符串str){
        // TODO自动生成方法存根
        STR1 = str.substring(0,str.indexOf(;));
        海峡= str.substring(str1.length()+ 1,str.length());
        STR2 = str.substring(0,str.indexOf(;));
        海峡= str.substring(str2.length()+ 1,str.length());
        STR3 = str.substring(0,str.indexOf(;));
        STR4 = str.substring(str3.length()+ 1,str.length());
    }
    @覆盖
    公共无效的onDestroy(){
        super.onDestroy();
        如果(处理!= NULL)
            handler.removeCallbacks(updateTimeTask);
        处理器= NULL;
    }
    私人处理程序处理程序=新的处理程序();
}


解决方案

当你使用处理程序 postDelayed 此功能会发生什么:


  1. 处理程序把你的的Runnable 到当前线程的活套队列中。

  2. 在当前时机成熟时,在的Runnable 您code是UI线程上运行的

请注意,它不是处理程序总是把的Runnable 来UI线程队列。它把的Runnable 电流线程的队列中,而当前线程的UI线程。

所以,如果你把视频下载在或任何费时的(如网络通讯) updateTimeTask 它会挂了整个UI线程。

在你的情况,你应该使用 ScheduledExecutorService的,见 scheduleWithFixedDelay 功能。或作为替代,你就可以开始的AsyncTask updateTimeTask 功能并尽一切繁重和视频下载 doInBackgrund 功能。

i am working on a task scheduler applications as my college project, i have a service that checks the expire time of an task. i had implemented handlers to check the expire time. When the expire time of an application is matched with current time then it sends a status bar notification. At this point i am pausing the Thread using Thread.sleep method for a minute, which is causing my application to hang. At logcat it shows heavy CPU usages by applications.

i am fetching the data from database, but it works fine when Thread.sleep is not called. Please help.

Here is the code:

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();
}

解决方案

When you're using Handler's postDelayed function here is what happens:

  1. Handler puts your Runnable into the current thread's Looper queue.
  2. When time comes, your code in Runnable is run on the UI thread.

Note that its not that Handler always puts Runnable to UI thread queue. It puts Runnable to current thread's queue, and your current thread was the UI thread.

So if you put Thread.sleep or anything time consuming (like network communication) in that updateTimeTask it will hang the whole UI thread.

In your case you should use ScheduledExecutorService, see scheduleWithFixedDelay function. Or as alternative, you can start AsyncTask from your updateTimeTask function and do all heavy-lifting and Thread.sleep in doInBackgrund function.

这篇关于在服务处理器和线程工作,使视频下载挂程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆