2017-04-09 77 views
1

我有聊天屏幕,我正在從FirebaeStorage下載附件。 我有各種格式的文件,可以發送doc,pdf,apk等,每個我有相同的TextViews和ImageViews。將onPostExecute值返回到RecyclerAdapter的onBindViewHolder中

在聊天屏幕的recyclerview適配器我設置本地存儲的文件路徑,它可以通過運行AsyncTask從Firebase存儲中下載文件並返回文件路徑來獲取。此工作完美,但問題是如何找回文件路徑onBindViewHolder上特別是如果其他

這裏是我的RecyclerAdapter這裏我打電話的AsyncTask和需要結果返回到相同的範圍和等到下載完成,然後根據數據集視圖返回

public void onBindViewHolder(final Chat_Adapter.ViewHolder holder, int position) { 


if (fileType.equals("pdf")){ 
new DownloadFileFromFS(Download_URL,FileName+".pdf").execute(); 

//HERE I NEED THE RESULT FROM ASYNCTASK AND WAIT TILL DOWNLOAD COMPLETES 
//THEN SET THE VIEWS WITH RETURN RESULT FROM ASYNCTASK 

    if (DownloadFilePath!=null){ 
     File file=new File(DownloadFilePath); 
     long sizeFile=file.length()/1024; //In KB 
     holder.Doc_FileName.setText(DownloadFilePath); 
     holder.Doc_FileSize.setText(String.valueOf(sizeFile)); 
    } 
    else { 
     Log.d(TAG,"DOWNLOAD FILE PATH IS NULL"); 
    } 

} 

的AsyncTask

public class DownloadAttachment extends AsyncTask<Void, String, String> { 
    String DownloadUrl,fileName; 
    File file; 
    Context context; 
    ProgressBar progressBar; 
    public static final String TAG="###Download Attachment"; 

    public DownloadAttachment(Context context, String downloadUrl, String fileName) { 
     DownloadUrl = downloadUrl; 
     this.fileName = fileName; 
     this.context=context; 
    } 


    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
    } 

    @Override 
    protected String doInBackground(Void... params) { 
     int count; 
     try { 
      File root = android.os.Environment.getExternalStorageDirectory(); 

      Log.d(TAG,"DO IN BACKGROUND RUNNING"); 
      File dir = new File(root.getAbsolutePath() + "/Downloaded Files/"); 
      if (dir.exists() == false) { 
       dir.mkdirs(); 
      } 


      URL url = new URL(DownloadUrl); //you can write here any link 
      file = new File(dir, fileName); 

      long startTime = System.currentTimeMillis(); 
      Log.d(TAG, "download begining"); 
      Log.d(TAG, "download url:" + url); 
      Log.d(TAG, "downloaded file name:" + fileName); 

     /* Open a connection to that URL. */ 
      URLConnection ucon = url.openConnection(); 

      //this will be useful so that you can show a typical 0-100% progress bar 
      int lengthOfFile=ucon.getContentLength(); 
     /* 
     * Define InputStreams to read from the URLConnection. 
     */ 
      InputStream is = ucon.getInputStream(); 
      BufferedInputStream bis = new BufferedInputStream(is); 

     /* 
     * Read bytes to the Buffer until there is nothing more to read(-1). 
     */ 
      ByteArrayOutputStream baf = new ByteArrayOutputStream(5000); 
      int current = 0; 
      long total=0; 
      while ((current = bis.read()) != -1) { 
       baf.write((byte) current); 
       total=total+current; 
       //PUBLISH THE PROGRESS 
       //AFTER THIS onProgressUpdate will be called 
       publishProgress(""+(int)(total*100)/lengthOfFile); 
      } 


     /* Convert the Bytes read to a String. */ 
      FileOutputStream fos = new FileOutputStream(file); 
      fos.write(baf.toByteArray()); 
      fos.flush(); 
      fos.close(); 
      Log.d("DownloadManager", "download ready in " + ((System.currentTimeMillis() - startTime)/1000) + " sec"); 
      Log.d(TAG,"File Path "+file); 

     } catch (IOException e) { 
      Log.d("DownloadManager", "Error: " + e); 
     } 

     return file.toString(); 
    }  

} 

UPDATE作爲@Atef野兔建議,我沒有在code.its實施工作正常,但如果我有不同的格式。如果從Asynctask獲得結果後如何調用特定的cuz代碼,建議只在調用pdf時聲明。

if (fileType.equals("pdf")){ 
    final String nameFile=UUID.randomUUID().toString(); 
    new DownloadFileFromFS(chat_wrapper.getDocuments(),nameFile).execute(); 

    filePathInterface=new FilePath() { 
     @Override 
     public void LocalFilePath(final String Path) { 
      //HERE I AM GETTING RESULT FROM ASYNCTASK 
      //AND SETTING VIEWS ACCORDING TO IT    
     } 
    }; 


} 
else if (fileType.equals("doc")){ 
//HOW TO GET RESULT FROM ASYNCTASK HERE IF FILETYPE IS "doc" 

} 
else if (fileType.equals("ppt")){ 
//HOW TO GET RESULT FROM ASYNCTASK HERE IF FILETYPE IS "ppt" 
} 
+0

見我的答案[這裏](http://stackoverflow.com/a/42656227/5993410) –

+0

@AtefHares我使用界面來獲得結果回到活動,但問題來了,我不得不等待下載完成,然後設置與數據的意見,並沒有等待它返回null – Ritu

+0

爲什麼你從調用調用Asynctask [R?你不應該使用適配器,除非你有數據將被顯示,而且,不要從適配器調用asynctask,從活動/片段調用它並獲取所需的數據,然後將其傳遞給適配器以顯示它 –

回答

1

好的使用接口 - 如你所知 - 將實現你所需要的!

只是做這樣的:

public interface AsyncTaskCallback { 
    void onSuccess (String filePath); 
} 

和適配器,沒有任何數據集的觀點,除非你獲得了數據從後面的AsyncTask,像這樣:

public void onBindViewHolder(final Chat_Adapter.ViewHolder holder, int position) { 

     //Initialize filetype here 

     new DownloadFileFromFS(Download_URL, FileName + "."+ filetype, new AsyncTaskCallback() { 
      @Override 
      public void onSuccess(String filePath) { 
       //HERE I NEED THE RESULT FROM ASYNCTASK AND WAIT TILL DOWNLOAD COMPLETES 
       //THEN SET THE VIEWS WITH RETURN RESULT FROM ASYNCTASK 

       if (filePath != null) { 
        File file = new File(filePath); 
        long sizeFile = file.length()/1024; //In KB 
        holder.Doc_FileName.setText(filePath); 
        holder.Doc_FileSize.setText(String.valueOf(sizeFile)); 
       } else { 
        Log.d(TAG, "DOWNLOAD FILE PATH IS NULL"); 
       } 
      } 
     }).execute(); 
    } 
+0

這種方法是正確的,但我認爲,但如果我有多種格式,如Doc,Docx等,我該如何創建不同的接口或不同的asynctask文件的每種格式 – Ritu

+0

@Ritu什麼意思通過創建不同的接口和asynctask? –

+0

在每個如果我正在檢查像上面的文件擴展名,如果文件是PDF的根據文件格式做任務。但問題就像你在'if(fileType.equals(「pdf」))中調用此接口'它只會爲'pdf'工作,但我可以做什麼在其他'如果(fileType.equals(「DOC」))或'如果(fileType.equals(「PPT」))等等,這就是爲什麼我問我需要嗎?爲每個格式或不同的asynctask創建不同的接口 – Ritu

0

您可以使用回調。

public interface FileDownloadCallback { 
    void onSuccess (String filePath); 
    void onFailed(); 

} 

將它傳遞給您的AsyncTask並從onPostExecute調用它。

+0

我使用接口,但問題是它將返回null cuz文件沒有下載,所以我必須等待直到下載完成,然後在調用'AsyncTask'後執行代碼 – Ritu

+1

@Ritu這就是爲什麼onPostExecute存在,在doInBackground中完成長時間運行任務之後 –

+0

好吧,假設你傳遞一個FileDownloadCallback給你的AsyncTask並將其賦給一個名爲mCallback的變量。在onPostExecute()中,您從doInBackground()(onPostExecute(String s))返回的字符串並調用mCallback.onSuccess()方法並將該String作爲參數傳遞。現在在您的視圖持有者中,從onSuccess()回調中設置您的TextView並執行其他任何您需要的操作。保證你的viewholder中的onSuccess()在AsyncTask完成執行之前不會被調用。 – jburn2712

相關問題