Async仅在单步执行调试器时有效

时间:2018-02-20 03:44:13

标签: java android android-studio pdf asynchronous

我的代码一直都是非常奇怪的行为。

基本上,我的代码使用输入/输出流从Internet下载.pdf文件,将其保存到内部存储(使用AsyncTask),然后使用外部“showPdf”库输出。

最奇怪的是它只适用于两个条件:

  1. 我运行代码两次(运行或调试没有任何断点)。调用showPdf()时,第一次运行日志 文件为空 ,但是当自己调用showPdf()时,第二次运行完全正常运行。
  2. 我调试代码并逐步完成程序
  3. 作为序言,我是java和android studio的新手,所以我的猜测可能根本不对,但我猜测因为InputStream是“异步”完成的,所以showPdf()可能在之前调用byte []数组被写入内存。如果是这种情况,我该怎么做才能将Async延迟足够长时间才能工作?

    public class pdfView extends AppCompatActivity {
        PDFView pdfView; //pdfView object
        String URL;
        String fileName;
        File directory; //path of created File
        // Container for all parameters of DownloadAsync
        private static class AsyncParameters {
            String URL;
            File directory;
            AsyncParameters(String URL, File directory) {
                this.URL = URL;
                this.directory = directory;
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_pdf_view);
    
            //Grab the extras from the intent call
            Intent intent = getIntent(); //whatever calls this activity, gather the intent
            URL = intent.getStringExtra("File URL"); // in this case, get the file name of the "extra" passed through
            fileName = intent.getStringExtra("File Name");
    
            //Grab the internal storage directory and create a folder if it doesn't exist
            File intDirectory = getFilesDir();
            File folder = new File(intDirectory, "pdf");
            boolean isDirectoryCreated = folder.exists();
    
            //See if the file exists
            if (!isDirectoryCreated) {
                isDirectoryCreated= folder.mkdir();
            }
            if(isDirectoryCreated) {
                directory = new File(folder, fileName);
                try {
                    directory.createNewFile();
                    if (directory.canWrite())
                        Log.d("hngggggggggggggg", "onCreate: ");
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                //See if file already exists
                boolean empty = directory.length() == 0;
                if (empty){
                    /**Call class to create parameter container**/
                    AsyncParameters param = new AsyncParameters(URL, directory);
                    DownloadAsync Downloader = new DownloadAsync();
                    Downloader.execute(param);
                    showPdf();
                }
                else
                    showPdf();
            }
    
        }
        public void showPdf()
        {
            pdfView = (PDFView) findViewById(R.id.pdfView);
            pdfView.fromFile(directory).load();
        }
    
        /**Class for asynchronous tasks**/
        public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
    
            // Container for all parameters of DownloadAsync
            ProgressDialog pDialog;
    
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                pDialog = new ProgressDialog(pdfView.this);
                pDialog.setMessage("Downloading Database...");
                String message= "Downloading Files";
    
                SpannableString ss2 =  new SpannableString(message);
                ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);
                ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0);
    
                pDialog.setMessage(ss2);
                pDialog.setCancelable(false);
                pDialog.show();
            }
    
            @Override
            protected Void doInBackground(AsyncParameters... params) {
                Log.d("WE ARE IN DOBACKGROUND", "doInBackground: ");
                String fileURL = params[0].URL;
                File directory = params[0].directory;
                try {
    
                    FileOutputStream f = new FileOutputStream(directory);
                    java.net.URL u = new URL(fileURL);
                    HttpURLConnection c = (HttpURLConnection) u.openConnection();
                    c.connect();
                    InputStream in = c.getInputStream();
    
                    byte[] buffer = new byte[8192];
                    int len1 = 0;
                    while ((len1 = in.read(buffer)) > 0) {
                        f.write(buffer, 0, len1);
                    }
                    f.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                onPostExecute();
                return null;
            }
    
            protected void onPostExecute() {
                pDialog.dismiss();
            }
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

您已经回答了自己的问题。由于下载是在不同线程上运行的asyncTask,因此在调用showPdf()之前无需等待asyncTask完成。您可以从后台任务完成后调用的showPdf()调用onPostExecute()。您的代码应如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ........
    ........

    AsyncParameters param = new AsyncParameters(URL, directory);
    DownloadAsync Downloader = new DownloadAsync();
    Downloader.execute(param);

    .......
    .......
}

public class DownloadAsync extends AsyncTask<AsyncParameters, Void, Void> {
    .......

    @Override
    protected void onPostExecute() {
        pDialog.dismiss();
        showPdf();
    }
}