在服务处理器和线程工作,使视频下载挂程序? [英] Working with handlers and threads in service, Thread.sleep makes the program to hang?
问题描述
我工作的一个任务调度程序为我的大学项目,我有一个检查任务的到期时间的服务。我已实施处理程序来检查过期时间。当应用程序的到期时间与当前的时间相匹配,然后它发送一个状态栏通知。在这一点上,我使用了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
此功能会发生什么:
- 处理程序把你的
的Runnable
到当前线程的活套队列中。 - 在当前时机成熟时,在
的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:
- Handler puts your
Runnable
into the current thread's Looper queue. - 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屋!