【问题标题】:Multiple downloading display in notification bar and also in activity通知栏和活动中的多个下载显示
【发布时间】:2015-12-31 06:42:47
【问题描述】:

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

【问题讨论】:

    标签: android


    【解决方案1】:

    循环器

    通过使用 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() 以使该线程充当管道。下一个 new Handler() 将被调用来处理这个线程上的消息队列。最后将调用 Looper.loop() 以开始运行消息循环。将使用 enqueueDownload(final DownloadTask task) 添加新任务。

    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" />
    

    Original Post Complete tutorial here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多