0

我的下载过程是:

    public class DownloadProcessor extends Thread 
    {
    public static final String TAG = "DownloadProcessor";

    private Download mDownload;

    private HttpGet mMethod = null;
    private DownloadHandler mHandler;

    public boolean mStopped = false;

    private Object lock = new Object();

    public DownloadProcessor(Download dl, DownloadHandler handler)
    {
            mDownload = dl;
            mHandler = handler;
    }

    public Download getDownload()
    {
            return mDownload;
    }

    private HttpClient getClient()
    {
            /* Set the connection timeout to 10s for our test. */
            HttpParams params = new BasicHttpParams();

            /* Avoid registering the https scheme, and thus initializing
             * SSLSocketFactory on Android.  Seems to be very heavy for some
             * reason. */
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(new Scheme("http",
              PlainSocketFactory.getSocketFactory(), 80));

            SingleClientConnManager cm =
              new SingleClientConnManager(params, schemeRegistry);

            return new DefaultHttpClient(cm, params);
    }

    public void run()
    {
            Log.d(TAG, "Connecting...");

            HttpClient cli = getClient();
            HttpGet method;

            method = new HttpGet(mDownload.url.toString());

            /* It's important that we pause here to check if we've been stopped
             * already.  Otherwise, we would happily progress, seemingly ignoring
             * the stop request. */
            if (mStopped == true)
                    return;

            synchronized(lock) {
                    mMethod = method;
            }

            HttpEntity ent = null;
            InputStream in = null;
            OutputStream out = null;

            try {
                    HttpResponse resp = cli.execute(mMethod);

                    if (mStopped == true)
                            return;

                    StatusLine status = resp.getStatusLine();

                    if (status.getStatusCode() != HttpStatus.SC_OK)
                            throw new Exception("HTTP GET failed: " + status);

                    if ((ent = resp.getEntity()) != null)
                    {
                            long len;
                            if ((len = ent.getContentLength()) >= 0)
                                    mHandler.sendSetLength(len);

                            in = ent.getContent();
                            out = new FileOutputStream(mDownload.getDestination());

                            byte[] b = new byte[2048];
                            int n;
                            long bytes = 0;

                            /* Note that for most applications, sending a handler message
                             * after each read() would be unnecessary.  Instead, a timed
                             * approach should be utilized to send a message at most every
                             * x seconds. */
                            while ((n = in.read(b)) >= 0)
                            {
                                    bytes += n;
                                    mHandler.sendOnRecv(bytes);     
                                    out.write(b, 0, n);
                            }
                    }

                    if (mStopped == false)
                            mHandler.sendFinished();
            } catch (Exception e) {
                    /* We expect a SocketException on cancellation.  Any other type of
                     * exception that occurs during cancellation is ignored regardless
                     * as there would be no need to handle it. */
                    if (mStopped == false)
                    {
                            mHandler.sendError(e.toString());
                            Log.e(TAG, "Unexpected error", e);
                    }
            } finally {
                    if (in != null)
                            try { in.close(); } catch (IOException e) {}

                    synchronized(lock) {
                            mMethod = null;
                    }

                    /* Close the socket (if it's still open) and cleanup. */
                    cli.getConnectionManager().shutdown();

                    if (out != null)
                    {
                            try { 
                                    out.close();
                            } catch (IOException e) {
                                    mHandler.sendError("Error writing output: " + e.toString());
                                    return;
                            } finally {
                                    if (mStopped == true)
                                            mDownload.abortCleanup();
                            }
                    }
            }
    }

    /**
     * This method is to be called from a separate thread.  That is, not the
     * one executing run().  When it exits, the download thread should be on
     * its way out (failing a connect or read call and cleaning up).
     */
    public void stopDownload(boolean _mStopped)
    {
        mStopped=_mStopped;
            /* As we've written this method, calling it from multiple threads would
             * be problematic. */
            if (mStopped == true)
                    return;

            /* Too late! */
            if (isAlive() == false)
                    return;

            Log.d(TAG, "Stopping download...");

            /* Flag to instruct the downloading thread to halt at the next
             * opportunity. */
            mStopped = true;

            /* Interrupt the blocking thread.  This won't break out of a blocking
             * I/O request, but will break out of a wait or sleep call.  While in
             * this case we know that no such condition is possible, it is always a
             * good idea to include an interrupt to avoid assumptions about the
             * thread in question. */
            interrupt();

            /* A synchronized lock is necessary to avoid catching mMethod in
             * an uncommitted state from the download thread. */
            synchronized(lock)
            {
                    /* This closes the socket handling our blocking I/O, which will
                     * interrupt the request immediately.  This is not the same as
                     * closing the InputStream yieled by HttpEntity#getContent, as the
                     * stream is synchronized in such a way that would starve our main
                     * thread. */
                    if (mMethod != null)
                            mMethod.abort();
            }

            mHandler.sendAborted();

            Log.d(TAG, "Download stopped.");
    }

    public void stopDownloadThenJoin()
    {
            stopDownload(true);

            while (true)
            {
                    try {
                            join();
                            break;
                    } catch (InterruptedException e) {}
            }
    }

public static class Download
{
    public URL url;
    public boolean directory;
    public File dst;
    public String name;
    public long length;

    public Download(URL url, File dst)
    {
            this.url = url;
            this.dst = dst;

            /* Figure out the filename to save to from the URL.  Note that
             * it would be better to override once the HTTP server responds,
             * since a better name will have been provided, possibly after
             * redirect.  But I don't care right now. */
            if ((directory = dst.isDirectory()) == true)
            {
                    String[] paths = url.getPath().split("/");

                    int n = paths.length;

                    if (n > 0)
                            n--;

                    if (paths[n].length() > 0)
                            name = paths[n];
                    else
                            name = "index.html";
            }
    }

    public File getDestination()
    {
            File f;

            if (directory == true)
                    f = new File(dst.getAbsolutePath() + File.separator + name);
            else
                    f = dst;

            return f;
    }

    /**
     * Delete the destination file, if it exists.
     */
    public void abortCleanup()
    {
            getDestination().delete();
    }
}   

}

我的线程是:

   public final DownloadHandler mHandler = new DownloadHandler()
{
        @Override
        public void handleMessage(Message msg)
        {
                DownloadProcessor.Download dl = mThread.getDownload();
                notification = new Notification(R.drawable.icon, "Downloading", System.currentTimeMillis());
                notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT;
                notification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download);
                notification.contentView.setProgressBar(R.id.status_progress, 100, 10, false);
                notification.contentView.setTextViewText(R.id.appName, name);
                ProgressBar status_progress = (ProgressBar) findViewById(R.id.status_progress);
                Button Cancelbutton = (Button) findViewById(R.id.Cancelbutton);
                status_progress.setMax(100); 

                final NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(
                        getApplicationContext().NOTIFICATION_SERVICE);

                notificationManager.notify(42, notification);
                switch (msg.what)
                {
                case MSG_FINISHED:
                    notificationManager.cancel(42);
                    Cancelbutton.setVisibility(View.GONE);
                    status_progress.setVisibility(View.GONE);
                        mThread = null;

                        Thread addAppDl=new Thread();
                        addAppDl.start();

                        Intent intent=new Intent(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.parse("file://"+Environment.getExternalStorageDirectory().toString()+"/.sabad/"+idApp+".apk"), "application/vnd.android.package-archive"); 
                        startActivityForResult(intent,1);
                        break;
                case MSG_SET_LENGTH:
                        dl.length = (Long)msg.obj;
                        break;
                case MSG_ON_RECV:
                        if (dl.length >= 0)
                        {
                                float prog =
                                  ((float)((Long)msg.obj) / (float)dl.length) * 100f;

                                notification.contentView.setProgressBar(R.id.status_progress, 100, (int)prog, false);
                                notification.contentView.setTextViewText(R.id.status_text, (int)prog+"%");
                                status_progress.setProgress((int)prog); 


                                // inform the progress bar of updates in progress
                                notificationManager.notify(42, notification);
                        }
                        else
                        {
                            float prog =
                                    ((float)((Long)msg.obj) / (float)dl.length) * 100f;
                                notification.contentView.setProgressBar(R.id.status_progress, 100, (int)prog, false);
                                notification.contentView.setTextViewText(R.id.status_text, (int)prog+"%");
                                status_progress.setProgress((int)prog); 


                                  // inform the progress bar of updates in progress
                                  notificationManager.notify(42, notification);                            }
                        break;
                case MSG_ERROR:
                    notificationManager.cancel(42);
                    Cancelbutton.setVisibility(View.GONE);
                    status_progress.setVisibility(View.GONE);
                        mThread = null;
                        Toast.makeText(getApplicationContext(), "Error: " + msg.obj,
                          Toast.LENGTH_LONG).show();
                        break;
                default:
                        super.handleMessage(msg);
                }
        }
};      

我开始使用以下代码下载:

                DownloadProcessor.Download dl = 
              new DownloadProcessor.Download(srcUrl, new File(dst));

            mThread = new DownloadProcessor(dl, mHandler);
            Cancelbutton.setVisibility(View.VISIBLE);
            status_progress.setVisibility(View.VISIBLE);

            mThread.start();  

但我想停止下载,我用这个

mThread.mStopped=true;
mThread.stopDownload(true);

但事实并非如此!

4

1 回答 1

0

这很简单。在您的时间里,您可以:

while ((n = in.read(b)) >= 0) {
    if (mStopped) {
       throw new CanceledException();
    } else {
        bytes += n;
        mHandler.sendOnRecv(bytes);     
        out.write(b, 0, n);
    }
}

因此,通过这种方式,您可以在单击按钮时将 mStopped 设置为 true,并且您的异常将被抛出并且您的线程将被杀死

于 2013-06-17T17:12:01.203 回答