多个下载显示在通知栏和活动中



现在在我的应用程序中下载代码正在工作,但当我下载多个文件时,它随机下载而不在队列中,我需要它在队列中下载,并且当前下载不显示在通知栏中,只显示在活动中。我想知道如何在通知栏中显示多次下载,并在当前活动中显示进度栏。感谢

环路

通过使用looper,您可以逐个下载队列中的多个文件。

步骤1:让我们创建DownloadThreadListener.java接口,该接口将用于获取线程更新。

package com.example.looper;
public interface DownloadThreadListener {
   void handleDownloadThreadUpdate();
}

步骤2:现在创建一个名为DownloadTask.java的类,它将模拟下载。我们将使用随机睡眠时间来模拟下载时间。

package com.example.looper;
import java.util.Random;
import android.util.Log;
/**
 * This is not a real download task. It just sleeps for some random time when
 * it's launched. The idea is not to require a connection and not to eat it.
 *
 */
public class DownloadTask implements Runnable {
   private static final String TAG = DownloadTask.class.getSimpleName();
   private static final Random random = new Random();
   private int lengthSec;
   public DownloadTask() {
      lengthSec = random.nextInt(3) + 1;
   }
   @Override
   public void run() {
      try {
         Thread.sleep(lengthSec * 1000);
         // it's a good idea to always catch Throwable
         // in isolated "codelets" like Runnable or Thread
         // otherwise the exception might be sunk by some
         // agent that actually runs your Runnable - you
         // never know what it might be.
      } catch (Throwable t) {
         Log.e(TAG, "Error in DownloadTask", t);
      }
   }
}

步骤3:现在让我们创建将充当管道的线程子类。首先,我们将调用Looper.prepare(),使该线程充当管道。下一个新的Handler()将被调用来处理该线程上的消息队列。最后将调用Looper.loop()来开始运行消息循环。新任务将使用enqueueDownload(最终的DownloadTask任务)添加。

package com.example.looper;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
public final class DownloadThread extends Thread {
   private static final String TAG = DownloadThread.class.getSimpleName();
   private Handler handler;
   private int totalQueued;
   private int totalCompleted;
   private DownloadThreadListener listener;
   public DownloadThread(DownloadThreadListener listener) {
      this.listener = listener;
   }
   @Override
   public void run() {
      try {
         // preparing a looper on current thread
         // the current thread is being detected implicitly
         Looper.prepare();
         Log.i(TAG, "DownloadThread entering the loop");
         // now, the handler will automatically bind to the
         // Looper that is attached to the current thread
         // You don't need to specify the Looper explicitly
         handler = new Handler();
         // After the following line the thread will start
         // running the message loop and will not normally
         // exit the loop unless a problem happens or you
         // quit() the looper (see below)
         Looper.loop();
         Log.i(TAG, "DownloadThread exiting gracefully");
      } catch (Throwable t) {
         Log.e(TAG, "DownloadThread halted due to an error", t);
      }
   }
   // This method is allowed to be called from any thread
   public synchronized void requestStop() {
      // using the handler, post a Runnable that will quit()
      // the Looper attached to our DownloadThread
      // obviously, all previously queued tasks will be executed
      // before the loop gets the quit Runnable
      handler.post(new Runnable() {
         @Override
         public void run() {
            // This is guaranteed to run on the DownloadThread
            // so we can use myLooper() to get its looper
            Log.i(TAG, "DownloadThread loop quitting by request");
            Looper.myLooper().quit();
         }
      });
   }
   public synchronized void enqueueDownload(final DownloadTask task) {
      // Wrap DownloadTask into another Runnable to track the statistics
      handler.post(new Runnable() {
         @Override
         public void run() {
            try {
               task.run();
            } finally {
               // register task completion
               synchronized (DownloadThread.this) {
                  totalCompleted++;
               }
               // tell the listener something has happened
               signalUpdate();
            }
         }
      });
      totalQueued++;
      // tell the listeners the queue is now longer
      signalUpdate();
   }
   public synchronized int getTotalQueued() {
      return totalQueued;
   }
   public synchronized int getTotalCompleted() {
      return totalCompleted;
   }
   // Please note! This method will normally be called from the download
   // thread.
   // Thus, it is up for the listener to deal with that (in case it is a UI
   // component,
   // it has to execute the signal handling code in the UI thread using Handler
   // - see
   // DownloadQueueActivity for example).
   private void signalUpdate() {
      if (listener != null) {
         listener.handleDownloadThreadUpdate();
      }
   }
}

步骤4:现在将全部功能添加到MainActivity.java。在这里,我们还将创建处理程序,以便在主线程上发布事件。

package com.example.looper;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity implements DownloadThreadListener,
      OnClickListener {
   private DownloadThread downloadThread;
   private Handler handler;
   private ProgressBar progressBar;
   private TextView statusText;
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      // Create and launch the download thread
      downloadThread = new DownloadThread(this);
      downloadThread.start();
      // Create the Handler. It will implicitly bind to the Looper
      // that is internally created for this thread (since it is the UI
      // thread)
      handler = new Handler();
      progressBar = (ProgressBar) findViewById(R.id.progress_bar);
      statusText = (TextView) findViewById(R.id.status_text);
      Button scheduleButton = (Button) findViewById(R.id.schedule_button);
      scheduleButton.setOnClickListener(this);
   }
   @Override
   protected void onDestroy() {
      super.onDestroy();
      // request the thread to stop
      downloadThread.requestStop();
   }
   // note! this might be called from another thread
   @Override
   public void handleDownloadThreadUpdate() {
      // we want to modify the progress bar so we need to do it from the UI
      // thread
      // how can we make sure the code runs in the UI thread? use the handler!
      handler.post(new Runnable() {
         @Override
         public void run() {
            int total = downloadThread.getTotalQueued();
            int completed = downloadThread.getTotalCompleted();
            progressBar.setMax(total);
            progressBar.setProgress(0); // need to do it due to a
                                 // ProgressBar bug
            progressBar.setProgress(completed);
            statusText.setText(String.format("Downloaded %d/%d", completed,
                  total));
            // vibrate for fun
            if (completed == total) {
               ((Vibrator) getSystemService(VIBRATOR_SERVICE))
                     .vibrate(100);
            }
         }
      });
   }
   @Override
   public void onClick(View source) {
      if (source.getId() == R.id.schedule_button) {
         int totalTasks = new Random().nextInt(3) + 1;
         for (int i = 0; i < totalTasks; ++i) {
            downloadThread.enqueueDownload(new DownloadTask());
         }
      }
   }
}

步骤5:添加振动权限

<uses-permission android:name="android.permission.VIBRATE" />

这里是原始的Post Complete教程。

最新更新