通过AsyncTask实现上传界面进度条、通知栏进度条同时刷新。

之前做一个项目,要求上传过程中,同时刷新上传界面中进度条和通知栏下拉页面中进度条。

一、我之前的做法是,在具体的下载方法中不停向两者发消息,通知更新进度。粗糙代码如下:

while ((len = is.read(buffer)) != -1) {                  
                    outStream.write(buffer, 0, len);

                    // 更新进度条
                    uploadSize += len;
                    progress = (int) (uploadSize * 100 / tempFile.length());
                    sendMessage(progress, tempFile);

                }

private void sendMessage(int progress, File tempFile) {
      
            if (handler_1 != null) {
                Message msg = new Message();
                msg.obj = tempFile.getPath();
                msg.what = Constant.UPLOADING;
                msg.arg1 = progress;
                handler_1.sendMessage(msg);
            }
            if (handler_2 != null) {
                Message msg = new Message();
                msg.obj = tempFile.getPath();
                msg.what = Constant.UPLOADING;
                msg.arg1 = progress;
                handler_2.sendMessage(msg);
            }       
    }

这样做的问题是:界面非常卡,下拉通知栏基本没反应,点击上传界面也没反应。

可能原因:消息发的太多,太频繁。

二、后来自己尝试用AsyncTask实现文件复制模拟上传/下载过程,两者同时刷新,界面不卡了,下拉通知栏也不卡。但是仍有一个问题:整个文件复制过程很漫长。

代码涉及主要文件:AsyncTaskUpdateProgressBarActivity.java、DownloadAsyncTask.java、AndroidManifest.xml、notification.xml

具体代码如下:

AsyncTaskUpdateProgressBarActivity.java

package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;
import android.widget.Toast;


public class AsyncTaskUpdateProgressBarActivity extends Activity {
    
    private static final String savePath = "/mnt/sdcard/dir/test/WinRAR.exe";
    private static final String src = "/mnt/sdcard/WinRAR.exe";
    private ProgressBar progressBar;
    private TextView text;
    private Button btn;
    
    private NotificationManager nm;
    private RemoteViews rv;
    private Notification notification;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progressBar = (ProgressBar)findViewById(R.id.progress_bar);
        text = (TextView)findViewById(R.id.text);
        
        //初始化通知栏RemoteViews中进度条
        nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        Intent intent = new Intent();
        PendingIntent pIntent = PendingIntent.getActivity(AsyncTaskUpdateProgressBarActivity.this, 0, intent, 0);        
        rv = new RemoteViews(getPackageName(), R.layout.notification);
        rv.setProgressBar(R.id.task_progress, 100, 0, false);
        
        notification = new Notification(R.drawable.icon, "正在上传", android.os.SystemClock.uptimeMillis());
        notification.defaults = Notification.DEFAULT_SOUND;
        notification.flags = Notification.FLAG_AUTO_CANCEL|Notification.FLAG_ONGOING_EVENT|Notification.FLAG_ONLY_ALERT_ONCE;
        notification.contentIntent = pIntent;
        notification.contentView = rv;
        
        final Object[] params = {src, progressBar, text, AsyncTaskUpdateProgressBarActivity.this, notification, nm};
        btn = (Button)findViewById(R.id.btn);
        btn.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //执行下载,更新界面进度条和通知中进度条
                DownloadAsyncTask downloadTask = new DownloadAsyncTask();
                downloadTask.execute(params);
            }
        });
    } 
}


DownloadAsyncTask.java

package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class DownloadAsyncTask extends AsyncTask
{
    private static final String savePath = "/mnt/sdcard/dir/test/WinRAR.exe";
    private ProgressBar progressBar;
    private TextView text;
    private Context context;
    
    private Notification notification;
    private NotificationManager nm;
    
    @Override
    protected Void doInBackground(Object... params)
    {
        String src = (String)params[0];
        progressBar = (ProgressBar)params[1];
        text = (TextView)params[2];
        context = (Context)params[3];
        notification = (Notification)params[4];
        nm = (NotificationManager)params[5];
        
        FileOutputStream fos = null;
        try
        {
            FileInputStream fis = new FileInputStream(src);
            File f = new File(savePath);
            if(!f.exists())
            {
                f.createNewFile();
            }
            fos = new FileOutputStream(f);
            long fileLength = fis.available();
            publishProgress(0);
            int numRead = -1;
            byte buf[] = new byte[1024];
            float downloadSize = 0;
            int progress = 0;
            while((numRead = fis.read(buf)) != -1)
            {
                fos.write(buf, 0, numRead);
                downloadSize += numRead;
                progress = (int)(downloadSize* 100/fileLength);
                publishProgress(progress);        
                
                //更新通知中进度条
                notification.contentView.setProgressBar(R.id.task_progress, 100, progress, false);
                nm.notify(0, notification);
            }
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;        
    }

    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);
        text.setText("onPostExecute");
        Toast.makeText(context, "下载完成", Toast.LENGTH_LONG).show();
        nm.cancel(0);
    }

    @Override
    protected void onProgressUpdate(Integer... values)
    {
        super.onProgressUpdate(values);
        progressBar.setProgress(values[0]);
    }

    @Override
    protected void onCancelled()
    {
        super.onCancelled();    
    }
    
}


AndroidManifest.xml


      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
   
    
   
                          android:label="@string/app_name">
           
               
               
           

       


   



notification.xml


    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:padding="10dip">
             android:id="@+id/task_progress"
        android:layout_width="fill_parent"
        android:layout_height="8dip"
        android:layout_marginTop="3dip"
        android:max="100"
        style="?android:attr/progressBarStyleHorizontal" />


已解决的问题:整个界面流畅

存在的问题:整个复制过程用时变长了。

望有高手指点,是不是用AsyncTask解决同时刷新进度条不太合适,还是具体处理过程中出了什么问题?




你可能感兴趣的:(android,app)