2014-03-06 34 views
3

我的意图是在应用第一次运行时创建下载服务,并每24小时检查一次更新。我原本一切都运行着我的主要活动,但似乎要在一个线程和一个类上运行一切。所以这是我的尝试,将其转移到另一个班级并投入使用。它假设在24小时内运行并检查更新,如果在4小时内没有互联网再次尝试。我特别想涉及任何递归问题,有两个或三个相同的服务检查更新,每24小时只有一个。但是将我的代码整合到服务中有问题,我做错了什么?Android IntentService更新循环

public class DownloadService extends IntentService { 

// TODO 0 - Define your Download Service as Android component in 
// AndroidManifest.xml 
private int result = Activity.RESULT_CANCELED; 

public DownloadService() { 
    super("DownloadService"); 
} 

// Will be called asynchronously be Android 
@Override 
protected void onHandleIntent(Intent intent) { 

    private final Runnable mUpdateUi = new Runnable(){ 
     public void run(){ 
      check(); 
     } 

    }; 

    private void start(){ 
     new Thread(
      new Runnable(){ 
       public void run(){ 
        Log.d(TAG, "inside start"); 
        Looper.prepare(); 
        mHandler = new Handler(); 
        check(); 
        Looper.loop(); 
       } 
      } 
     ).run(); 
    } 


    private void check(){ 
     if (isNetworkAvailable()== true){ 
      try { 
       new checkupdate().execute(); 
       delayTime = 86400000; 
       Toast.makeText(DownloadService.this, "Daily update check!", Toast.LENGTH_SHORT).show(); 
      } 
      catch (IOException e) { 
       e.printStackTrace(); 
       delayTime = 21600000; 
      } 
     }else{ 
      delayTime = 21600000; 
      Toast.makeText(DownloadService.this, "No internet for Daily update check, try again in little!", Toast.LENGTH_SHORT).show(); 
     } 
     reCheck(); 
    } 

    private void reCheck(){ 
     mHandler.postDelayed(mUpdateUi, delayTime); 
    } 

} 

回答

2

IntentService已处理设置工作线程和队列,并在队列为空时终止。这使得它成为像下载服务那样管理下载数据的实际工作的非常好的候选人,但对于时间调度程序来说并不是一个很好的候选人。

我建议使用AlarmManager来安排你的工作。你想要的是触发一个意图启动你的下载服务,通过发送一个指示要做什么的动作意图。

还要注意的是,如果你想取消与行动的IntentService,你将需要实现onStartCommand除了通常的onHandleIntent,这样您就可以立即行动回应 - 你不能从onHandleIntent做到这一点,因为在队列中的当前任务完成之前,意图不会被发送到该目标。这里有一个简单的例子:

public class DownloadService extends IntentService { 

    private static final String TAG = "DownloadService"; 

    //////////////////////////////////////////////////////////////////////// 
    // Actions 

    public static final String ACTION_CANCEL = "package.name.DownloadService.action.CANCEL"; 
    public static final String ACTION_DOWNLOAD = "package.name.DownloadService.action.DOWNLOAD"; 

    //////////////////////////////////////////////////////////////////////// 
    // Broadcasts 

    public static final String BROADCAST_DOWNLOADED = "package.name.DownloadService.broadcast.DOWNLOADED"; 
    public static final String BROADCAST_ERROR  = "package.name.DownloadService.broadcast.ERROR"; 

    //////////////////////////////////////////////////////////////////////// 
    // Extras 

    public static final String MESSAGE = "package.name.DownloadService.extra.MESSAGE"; 
    // etc. 

    private boolean isCancelled; 

    // usual stuff omitted 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(intent != null) { 
      String action = intent.getAction(); 
      Log.v(TAG, "onStartCommand() - action: "+action); 
      if(ACTION_CANCEL.equals(action)) { 

       isCancelled = true; 

       // insert code here to signal any objects to cancel 
       // their work, etc. 

       stopSelf(); 
      } 
     } 

     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     if(intent != null) { 
      final String action = intent.getAction(); 
      Log.v(TAG, "onHandleIntent() - action: "+action); 
      if(ACTION_DOWNLOAD.equals(action)) { 
       handleDownloading(intent); 
      } 
      else if(ACTION_CANCEL.equals(action)) { 
       // nothing to do here, handled in onStartCommand 
      } 
     } 
    } 

    //////////////////////////////////////////////////////////////////// 

    private void handleDownloading(Intent intent) { 

     // get stuff you need from the intent using intent.getStringExtra(), etc. 

     if(!isCancelled) { 
      // do downloading, call broadcastDownloaded() when done 
     } 
     else { 
      // stop work, send broadcast to report cancellation, etc. 
     } 
    } 

    // send a broadcast to a BroadcastReceiver (e.g. in your activity) 
    // to report that the download completed 
    private void broadcastDownloaded() { 
     Log.v(TAG, "broadcastDownloaded()"); 
     Intent broadcastIntent = new Intent(); 
     if (broadcastIntent != null) { 
      broadcastIntent.setAction(BROADCAST_DOWNLOADED); 
      broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
      sendBroadcast(broadcastIntent); 
     } 
    } 

    private void broadcastError(String message) { 
     Log.v(TAG, "broadcastError(), message: "+message); 
     Intent broadcastIntent = new Intent(); 
     if (broadcastIntent != null) { 
      broadcastIntent.setAction(BROADCAST_ERROR); 
      broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
      if(message != null) { 
       broadcastIntent.putExtra(MESSAGE, message); 
      } 
      sendBroadcast(broadcastIntent); 
     } 
    } 
} 
+0

这非常有趣,并感谢您的回应!我目前正在将我的下载内容发送到下载管理器,那么您还会使用意向服务的兄弟吗?我无法废除意图服务的想法,只需使用警报管理器在24小时内触发检查更新,然后像往常一样将下载文件发送到下载管理器? – MAXGEN

+0

如果你使用'android.app。DownloadManager'然后不,你不需要使用IntentService。关于使用自己的IntentService的唯一原因是在调用DownloadManager之前立即执行一些其他任务 - 因为IntentService实现了一个工作队列,所以它可以是链接任务的便捷方式。根据你所描述的内容,虽然在这种情况下我没有看到任何需要。 DownloadManager已经以更健壮和灵活的方式做了你自定义的IntentService需要做的事情。 –

+0

“...除了通常的onHandleIntent之外,您还需要实现onStartCommand ...” - 谢谢。我一直在努力更新我的'IntentService'行动。 –

0

这不是IntentService是如何使用的。根据documentation,IntentService已经创建了自己的工作线程。您不应该创建自己的:

客户端通过startService(Intent)调用发送请求;该服务根据需要启动,使用工作线程轮流处理每个Intent,并在其停止工作时自行停止。

除了事实如下所示不会编译你的代码(你start方法是onHandleIntent方法内),您的一般态度似乎开始自己的工作线程。这种方法会发生什么,你会开始线程,onHandleIntent将完成,然后服务将被停止。除了实际上没有工作,这种方法也是一个坏主意,因为(最好如果你幸运的话)服务将连续24/7运行。

你应该做的是实际做你的主要工作onHandleIntent其中IntentService将排队在你的工作线程。然后,使用postDelayed而不是使用AlarmManager来设置闹钟,以便在24小时或4小时内发送Intent以再次启动服务。

+0

那么我应该打电话给服务来做我的更新工作吗?所以我在服务中运行这段代码的目的是因为我在与其他runnable或handler处理同一主线程时遇到问题。所以我现在不知道该怎么办?这是我原来的发帖。 https://stackoverflow.com/questions/22184419/android-delay-check-for-update-recursive/22184754?noredirect=1#22184754 – MAXGEN