0

ボタンとラベルのあるアクティビティがあります。ボタンをクリックすると、アプリはいくつかのファイル(約9000)をダウンロードする必要があります。ユーザーがボタンをもう一度クリックした場合、ダウンロードを停止し、もう一度クリックすると最初からダウンロードを開始する必要があります。

だからこれは私がすることです:

活動中:

    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;
        }
    });

ファイルをダウンロードする必要があるスレッドは次の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_;
    }
}

私の問題は、ユーザーがボタンを2回クリックしたときに発生します(ダウンロードを停止して再開します)。プロンプトエラーは、スレッドがすでに開始されて実行中であることを示しています。どうすれば解決できますか?asyncTaskの方が優れているはずですが、アプリケーションで問題が発生しているため、実行中のスレッドが非常に多く、デバイスのパフォーマンスが非常に低くなっています。スレッドを確実に停止することは可能ですか?他にもっと良い解決策はありますか?

4

2 に答える 2

1

AsyncTaskを実装してみてください。ユーザーが最初にボタンをタップしたときに、タスクのを呼び出しますexecute (Params... params)。2回目のタップで、タスクのを呼び出しますcancel (boolean mayInterruptIfRunning)。タスクのにダウンロード機能を配置しますdoInBackground (Params... params)

于 2013-02-11T18:01:24.643 に答える
0

実行スレッドは時々isInterrupted()をチェックし、trueが返された場合は終了する必要があります。そうしないと、スレッドがキャンセルされることはありません。

しかし、あなたのアーキテクチャ全体は間違っていると思います。9000ファイルを携帯電話にダウンロードしますか?各ファイルがわずか1KBであっても、それはモバイルアプリにとって膨大な量のメモリです。そして、少なくとも、自分の正気のために、そのデータを圧縮してzipをダウンロードする必要があります。

于 2013-02-11T16:40:37.850 に答える