2017-04-09 67 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

相关问题