简体   繁体   English

如何在Android中启动和停止下载多个文件

[英]How to start and stop the download of multiple files in android

i've an activity with a button and a label. 我有一个带有按钮和标签的活动。 On button click my app must download several files ( about 9000 ). 在按钮上单击我的应用程序必须下载几个文件(大约9000个)。 If user clicks again on button, the download must stop and on another click it must start from the beginning. 如果用户再次单击按钮,则下载必须停止,并且再次单击必须从头开始。

So this is what i do: 所以这就是我要做的:

In activity: 活动中:

    file.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Button b = (Button)v;
            if(canFile){
                b.setText("Stop download");
                changeLabelInfo("Getting file list...");
                labelFile.setVisibility(View.VISIBLE);
                fileTask.start();
            }else{
                b.setText("Download files");
                if(fileTask.isAlive()){  
                   fileTask.interrupt();
                   fileTask = null;
                   fileTask = new UpdateFilesThread(this);
                }
                labelFile.setVisibility(View.INVISIBLE);
                Kernel.setManualUpdate("file",false);
            }
            canFile = !canFile;
        }
    });

The thread that must download files is UpdateFilesThread : 必须下载文件的线程是UpdateFilesThread

public class UpdateFilesThread extends Thread{
    private MainActivity activity;
    private final String rootPath = "/mnt/local/";
    public UpdateFilesThread(MainActivity activity){
        this.activity = activity;
    }


    public void run(){
        String json = getFilesURL();
        JSONObject a = (JSONObject)JSONValue.parse(json);
        boolean isZip = false,canDownload = true;
        String[] keys = new String[]{"key1","key2","key3","key4"};

        for(String key:keys){
            Object folder = (Object)a.get(key);
            if(folder instanceof JSONObject){
                JSONObject fold = (JSONObject)folder;
                for(Object path_o:fold.keySet()){
                    path = path_o.toString().replace(" ", "%20");
                    if(local.endsWith(".php")){
                        isZip = true;
                        try {
                            Jsoup.connect(mywebserviceURL).data("path",path).timeout(0).post(); // If php generate zip containing php file
                        } catch (IOException e) {
                            canDownload = false;
                        }
                    }
                    if(canDownload){
                        try{
                            if(downloadFromUrl(path,isZip))
                                //SAVE URL DOWNLOADED
                        }catch(Exception e){
                            e.printStackTrace();
                        }
                    }
                    canDownload = true;
                    isZip = false;
                }
            }
        }
        a.remove(key);
    }

    private String getFilesURL(){
        try {

            MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
            entity.addPart("type", new StringBody("all"));
            HttpPost post = new HttpPost("mywebserviceURL");
            post.setEntity(entity);
            HttpClient client = new DefaultHttpClient();
            HttpResponse response = client.execute(post);

            return EntityUtils.toString(response.getEntity());
        } catch (UnsupportedEncodingException e) {
            Support.writeError(e, null);
            e.printStackTrace();
            return "";
        } catch (ClientProtocolException e) {
            Support.writeError(e, null);
            e.printStackTrace();
            return "";
        } catch (ParseException e) {
            Support.writeError(e, null);
            e.printStackTrace();
            return "";
        } catch (IOException e) {
            Support.writeError(e, null);
            e.printStackTrace();
            return "";
        }
    }
    public boolean downloadFromUrl(String path,boolean isZip){
        InputStream is = null;
        FileOutputStream fos = null;
        String localFilename = rootPath+path;
        String local = isZip?rootPath+"tmp.zip":localFilename;


        boolean return_ = false;
        try {
            URL url = new URL(isZip?mywebserviceURLZip:mywebserviceURLZip+path);
            URLConnection urlConn = url.openConnection();
            urlConn.setReadTimeout(0);
            is = urlConn.getInputStream();
            fos = new FileOutputStream(local);

            byte[] buffer = new byte[51200];
            int len;

            while ((len = is.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }
            fos.close();
            is.close();
            if(isZip){
                ZipFile zip = new ZipFile(local);
                zip.extractAll(rootPath);
                new File(local).delete();
            }

            return_= true;
        }catch(Exception e){
            e.printStackTrace();
            return false;
        }
        return return_;
    }
}

My problem borns when user clicks two time the button ( stop downloading and start again ). 当用户单击两次按钮时,我的问题就产生了(停止下载并重新开始)。 The prompt error says that the thread is already startend and in running.. how can i solve it? 提示错误提示该线程已经开始并且正在运行中。我该如何解决? I know that asyncTask should be better but i've problem cause in my application there are so many thread running and the device is so poorly peforming.. It's possible to stop definitelly a thread? 我知道asyncTask应该会更好,但是我有问题,原因是我的应用程序中正在运行许多线程,而设备执行性能却很差。是否可以肯定地停止线程? are there other better solution? 还有其他更好的解决方案吗?

Try implementing an AsyncTask . 尝试实现AsyncTask When the user first taps the button call the task's execute (Params... params) . 当用户第一次点击按钮时,将调用任务的execute (Params... params) On the second tap call the task's cancel (boolean mayInterruptIfRunning) . 在第二次点击时调用任务的cancel (boolean mayInterruptIfRunning) Put the download functionality in the task's doInBackground (Params... params) 将下载功能放在任务的doInBackground (Params... params)

Your run thread needs to occasionally check isInterrupted() and exit if it returns true. 您的运行线程有时需要检查isInterrupted()并在返回true时退出。 Otherwise the thread will never be canceled. 否则,该线程将永远不会被取消。

I think your entire architecture is wrong though. 我认为您的整个体系结构都是错误的。 Downloading 9000 files onto a mobile phone? 将9000个文件下载到手机上? Even if each file is only 1KB, that's a huge amount of memory for a mobile app. 即使每个文件只有1KB,对于移动应用程序来说,这也是巨大的内存。 And at the very least you ought to zip up that data and download a zip, for your own sanity. 至少出于您的理智,您应该压缩这些数据并下载一个zip。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM