2017-08-24 36 views
0

我在onActivityResult()內部有一個for循環,該方法創建Runnable對象並將其分配到AsyncTask。每個Runnable對象負責在pdf文件上操作,使用密碼對其進行密封,然後使用Intent啓動startActivityForResult()方法發送電子郵件。Android使AsyncTask等待在for循環內恢復活動

除了我的問題是for循環會立即啓動所有AsyncTask,即使活動已暫停並且用戶在電子郵件客戶端應用程序中,一切都可以起作用。我想要確保下一個AsyncTask不會執行,直到用戶在電子郵件客戶端應用程序上按下發送電子郵件按鈕後回到應用程序。

UPDATE

if (requestCode == 2) { 
     // Create Insurer annexe, seal document with insurer password and trigger sending email 
     int lastInsurerPosition = -1; 
     for (int i = 0; i < Constat.getInstance().getAccidentList().size(); i++) { 
      if (Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition() != -1 && 
        !insurersEmails[Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition()].equals("null") && 
        Constat.getInstance().getAccidentList().get(i).getSendOption() != 1 && 
        Constat.getInstance().getAccidentList().get(i).getSendOption() != 2) { 
       lastInsurerPosition = i; 
      } 
     } 
     if (lastInsurerPosition != -1) { 
      final int lastInsurerPositionCopy = lastInsurerPosition; 

      for (int i = 0; i < Constat.getInstance().getAccidentList().size(); i++) { 
       String insurerEmail = "null"; 
       if (Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition() != -1) { 
        insurerEmail = insurersEmails[Constat.getInstance().getAccidentList().get(i).getCar().getInsurerPosition()]; 
       } 
       if (Constat.getInstance().getAccidentList().get(i).getSendOption() != 1 && 
         Constat.getInstance().getAccidentList().get(i).getSendOption() != 2 && 
         !insurerEmail.equals("null")) { 
        final int finalI = i; 
        Runnable progressRunnable = new Runnable() { 
         @Override 
         public void run() { 
          try { 
           String[] toArray = new String[1]; 
           toArray[0] = insurersEmails[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()]; 
           String subject = getResources().getString(R.string.pdf_joint_report); 

           InputStream is; 
           String str; 
           byte[] buffer = null; 
           int size; 

           if (Locale.getDefault().getLanguage().equals("en")) { 
            is = getAssets().open("insurerEmailTemplateENG.html"); 
           } else { 
            is = getAssets().open("insurerEmailTemplateFR.html"); 
           } 
           size = is.available(); 

           buffer = new byte[size]; 
           is.read(buffer); 
           is.close(); 

           String destPath = Constat.getInstance().getPdfPath().replace(".pdf", "_copy" + Constat.getInstance().getAccidentList().get(finalI).getNumAccident() + ".pdf"); 
           String destPath1 = Constat.getInstance().getPdfPath().replace(".pdf", "_copy1.pdf"); 

           if (insurersPdfStructure[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()].equals("1")) { 
            List<File> filesList = new ArrayList<>(); 
            if (PdfController.getInstance(activityRef.get()).getAnnexePref()) { 
             filesList.add(new File(Constat.getInstance().getPdfPath())); 
             filesList.add(new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/annexe.pdf")); 
            } else { 
             filesList.add(new File(Constat.getInstance().getPdfPath())); 
            } 
            File outputFile = new File(destPath1); 
            try { 
             Utilities.mergePdfDocuments(filesList, outputFile); 
            } catch (DocumentException | IOException e) { 
             e.printStackTrace(); 
            } 

           } else { 
            try { 
             Document document = new Document(PageSize.A4); 
             PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destPath1)); 

             document.open(); 
             PdfContentByte cb = writer.getDirectContent(); 

             PdfReader reader = new PdfReader(new FileInputStream(Constat.getInstance().getPdfPath())); 
             for (int j = 0; j < reader.getNumberOfPages(); j++) { 
              PdfImportedPage page = writer.getImportedPage(reader, j + 1); 
              if (j == 0) { 
               PdfDictionary parameters = new PdfDictionary(); 
               parameters.put(PdfName.MODDATE, new PdfDate()); 

               PdfFileSpecification fileSpec = PdfFileSpecification.fileEmbedded(
                 writer, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/annexe.xml", 
                 "annexe.xml", null, "application/xml", parameters, 0); 
               fileSpec.put(new PdfName("annexe"), new PdfName("Data")); 
               writer.addFileAttachment("annexe.xml", fileSpec); 

               PdfFileSpecification fileSpec1 = PdfFileSpecification.fileEmbedded(
                 writer, Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + PACKAGE_NAME + "/xml_def.xsd", 
                 "xml_def.xsd", null, "application/xml", parameters, 0); 
               fileSpec.put(new PdfName("xml_def"), new PdfName("Data")); 
               writer.addFileAttachment("xml_def.xsd", fileSpec1); 

               PdfArray array = new PdfArray(); 
               array.add(fileSpec.getReference()); 
               array.add(fileSpec1.getReference()); 
               writer.getExtraCatalog().put(new PdfName("AF"), array); 
              } 
              cb.addTemplate(page, 0, 0); 
              document.newPage(); 
             } 

             document.close(); 

            } catch (DocumentException | IOException e) { 
             e.printStackTrace(); 
            } 
           } 

           try { 
            File file1 = new File(destPath); 
            file1.getParentFile().mkdirs(); 
            Utilities.sealPdf(destPath1, destPath, insurersPasswords[Constat.getInstance().getAccidentList().get(finalI).getCar().getInsurerPosition()]); 
           } catch (DocumentException e) { 
            e.printStackTrace(); 
           } 

           ArrayList<Uri> uris = new ArrayList<Uri>(); 
           if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 
            uris.add(Uri.fromFile(new File(destPath))); 
           else 
            uris.add(FileProvider.getUriForFile(context, getApplicationContext().getPackageName() + ".provider", new File(destPath))); 

           str = new String(buffer); 
           str = str.replace("{#CAROWNER}", Constat.getInstance().getAccidentList().get(finalI).getCar().getOwner().getFirstName() + " " + Constat.getInstance().getAccidentList().get(finalI).getCar().getOwner().getLastName()); 

           final int i1 = finalI; 
           final int lastInsurerPosition1 = lastInsurerPositionCopy; 
           final String[] toArray1 = toArray; 
           final String str1 = str; 
           final String subject1 = subject; 
           final ArrayList<Uri> uris1 = uris; 

           runOnUiThread(new Runnable() { 
            @Override 
            public void run() { 
             if (i1 != lastInsurerPosition1) { 
              Utilities.sendEmails(activityRef.get(), toArray1, null, str1, subject1, uris1, 3); 
             } else { 
              Utilities.sendEmails(activityRef.get(), toArray1, null, str1, subject1, uris1, 4); 
             } 
             while (!activityRef.get().hasWindowFocus()) { 
              try { 
               Thread.sleep(2000); 
              } catch (InterruptedException e) { 
               e.printStackTrace(); 
              } 
             } 
            } 
           }); 

          } catch (IOException e) { 
           e.printStackTrace(); 
          } 
         } 
        }; 
        LongOperation lo = new LongOperation(PdfActivity.this, progressRunnable, getResources().getString(R.string.generating), 
          getResources().getString(R.string.generating_email_n_for_insurer, Constat.getInstance().getAccidentList().get(i).getDriver().getFirstName())); 
        lo.execute(); 
       } 
      } 
     } else { 
      // delete signature image file and redirect user to home screen 
      for (int j = 0; j < Constat.getInstance().getAccidentList().size(); j++) { 
       File file = new File(Constat.getInstance().getAccidentList().get(j).getSignatureFilePath()); 
       file.delete(); 
      } 

      // Reset Pdf instance 
      PdfController.destroyInstance(); 

      AlertDialog.Builder builder = new AlertDialog.Builder(context); 
      builder.setTitle(getResources().getString(R.string.send_success)) 
        .setMessage(getResources().getString(R.string.emails_sended)) 
        .setCancelable(false) 
        .setPositiveButton(getResources().getString(R.string.ok_button), new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
          Intent intent = new Intent(context, MainActivity.class); 
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
          startActivity(intent); 
         } 
        }); 
      AlertDialog alert = builder.create(); 
      alert.show(); 

     } 

    } 

在此先感謝。

+4

可以請你出示一些你的代碼,以便更好地理解這個問題。 – Danger

+0

@丹格請查閱我的帖子更新。 –

+0

有一件事,你永遠不應該有超過5個在Android的時間運行的AsynTasks。 – Danger

回答

1

我可以寫一個抽象的片斷,因爲我不明白你的代碼,它可以引導了(如果有幫助)來改變你的代碼,我會後回答

聲明這個類範圍

Queue<MyItem> queue = new LinkedList<MyItem>(); 
//MyItem is a type i think it's what in 'Constat.getInstance().getAccidentList()' 
//it should be the type you have to be processed (email and PDF) 

你當前的代碼(onActivityResult)不開始處理,只需添加到隊列中,處理中的第一項隊列:每次的onResume()

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    for(int i = 0; i < Constat.getInstance().getAccidentList().size(); i++){ 
     //add to-be-processed items in the Queue 
     queue.add(Constat.getInstance().getAccidentList().get(i)); 
    }//for loop 

    //when loop finish, start processing first item 
    MyItem item = queue.remove(); 
    processItem(item); 
} 

被調用,檢查隊列大小如果空 ,可以是所有項目進行了處理,或者這是第一次活動是開放的,所以沒有項目來處理尚未

@Override 
protected void onResume() 
{ 
    super.onResume(); 
    if(queue.size() != 0){ 
     processItem(queue.remove()); 
    }//we still have items to process 
} 

實際的代碼是在這裏,創建PDF,創建電子郵件,發送電子郵件。

private void processItem(MyItem item){ 
    //start runnable ... to create PDF ... 

    //create email body, and start email sending action 
} 
+1

我採用了你的解決方案。 在for循環中,我爲列表上的每個Accident構造了一個Runnable對象。然後將其添加到隊列中。 在onResume()方法中,我檢查隊列是否爲空,然後繼續執行可執行runnable的asynctask。 謝謝你寶貴的答案。 –

+1

@mohammedaouledissa這是一個很好的,很高興我可以幫助 – Yazan