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

Java 异步仅在单步执行调试器时有效,java,android,android-studio,pdf,asynchronous,Java,Android,Android Studio,Pdf,Asynchronous,我的代码中出现了非常奇怪的行为 基本上,我的代码是使用输入/输出流从internet下载.pdf文件,将其保存到内部存储器(使用异步任务),然后使用外部的“showPdf”库输出 最奇怪的是,它只在两个条件下起作用: 我运行代码两次(在没有断点的情况下运行或调试)。调用showPdf()时,第一次运行日志文件为空,但单独调用showPdf()时,第二次运行完全正常 我调试代码并逐步完成程序 作为前言,我是java和android studio的新手,所以我的猜测可能根本不对,但我猜测,由于Inp

我的代码中出现了非常奇怪的行为

基本上,我的代码是使用输入/输出流从internet下载.pdf文件,将其保存到内部存储器(使用异步任务),然后使用外部的“showPdf”库输出

最奇怪的是,它只在两个条件下起作用:

  • 我运行代码两次(在没有断点的情况下运行或调试)。调用showPdf()时,第一次运行日志文件为空,但单独调用showPdf()时,第二次运行完全正常
  • 我调试代码并逐步完成程序
  • 作为前言,我是java和android studio的新手,所以我的猜测可能根本不对,但我猜测,由于InputStream是“异步”完成的,showPdf()可能会在字节[]数组写入内存之前被调用。如果是这种情况,我可以做什么来延迟异步足够长的时间来工作

    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();
            }
        }
    
    }
    
    公共类pdfView扩展了AppCompative活动{
    PDFView PDFView;//PDFView对象
    字符串URL;
    字符串文件名;
    文件目录;//已创建文件的路径
    //DownloadAsync所有参数的容器
    私有静态类异步参数{
    字符串URL;
    文件目录;
    异步参数(字符串URL、文件目录){
    this.URL=URL;
    this.directory=目录;
    }
    }
    @凌驾
    创建时受保护的void(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\uPDF\u视图);
    //从意向电话中获取额外信息
    Intent Intent=getIntent();//无论调用什么活动,都要收集意图
    URL=intent.getStringExtra(“文件URL”);//在本例中,获取传递的“extra”的文件名
    fileName=intent.getStringExtra(“文件名”);
    //抓取内部存储目录并创建一个不存在的文件夹
    File intDirectory=getFilesDir();
    文件夹=新文件(intDirectory,“pdf”);
    布尔值isDirectoryCreated=folder.exists();
    //查看文件是否存在
    如果(!isDirectoryCreated){
    isDirectoryCreated=folder.mkdir();
    }
    如果(isDirectoryCreated){
    目录=新文件(文件夹、文件名);
    试一试{
    createNewFile()目录;
    if(directory.canWrite())
    Log.d(“hngggggggg”,“onCreate:”);
    }捕获(IOE1异常){
    e1.printStackTrace();
    }
    //查看文件是否已经存在
    布尔空=目录。长度()==0;
    if(空){
    /**调用类来创建参数容器**/
    AsyncParameters param=新的AsyncParameters(URL、目录);
    DownloadAsync Downloader=新的DownloadAsync();
    Downloader.execute(param);
    showPdf();
    }
    其他的
    showPdf();
    }
    }
    公开资料PDF(
    {
    pdfView=(pdfView)findViewById(R.id.pdfView);
    pdfView.fromFile(directory.load();
    }
    /**用于异步任务的类**/
    公共类DownloadAsync扩展AsyncTask{
    //DownloadAsync所有参数的容器
    ProgressDialog;
    @凌驾
    受保护的void onPreExecute(){
    super.onPreExecute();
    pDialog=newprogressdialog(pdfView.this);
    setMessage(“正在下载数据库…”);
    String message=“下载文件”;
    SpannableString ss2=新的SpannableString(消息);
    ss2.setSpan(新的相对跨度(2f),0,ss2.length(),0);
    ss2.setSpan(新的ForegroundColorSpan(Color.BLACK),0,ss2.length(),0);
    pDialog.setMessage(ss2);
    pDialog.setCancelable(假);
    pDialog.show();
    }
    @凌驾
    受保护的Void doInBackground(异步参数…参数){
    Log.d(“我们在DOBACKGROUND”,“doInBackground:”);
    字符串fileURL=params[0]。URL;
    文件目录=参数[0]。目录;
    试一试{
    FileOutputStream f=新的FileOutputStream(目录);
    java.net.URL u=新URL(fileURL);
    HttpURLConnection c=(HttpURLConnection)u.openConnection();
    c、 connect();
    InputStream in=c.getInputStream();
    字节[]缓冲区=新字节[8192];
    int len1=0;
    而((len1=in.read(buffer))>0){
    f、 写入(缓冲区,0,len1);
    }
    f、 close();
    }捕获(例外e){
    e、 printStackTrace();
    }
    onPostExecute();
    返回null;
    }
    受保护的void onPostExecute(){
    pDialog.disclose();
    }
    }
    }
    
    您已经回答了自己的问题。由于下载是在不同线程上运行的asyncTask,因此在调用
    showPdf()
    之前,无需等待asyncTask完成。您可以从
    onPostExecute()
    调用
    showPdf()
    ,该函数在后台任务完成后调用。您的代码应该如下所示:

    @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();
        }
    }
    
    @覆盖
    创建时受保护的void(Bundle savedInstanceState){
    ........
    ........
    AsyncParameters param=新的AsyncParameters(URL、目录);
    DownloadAsync Downloader=新的DownloadAsync();
    Downloader.execute(param);
    .......
    .......
    }
    公共类DownloadAsync扩展AsyncTask{
    .......
    @凌驾
    受保护的void onPostExecute(){
    pDialog.disclose();
    showPdf();
    }
    }
    
    我认为您不理解异步的含义。您的aynctask不一定在您的其他任务之前完成function@njzk2我很清楚这一点。我的意思是更多,以便异步任务能够正常工作