Android 将参数传递到异步任务

Android 将参数传递到异步任务,android,parameters,android-asynctask,imageview,drawable,Android,Parameters,Android Asynctask,Imageview,Drawable,大家好,我正在尝试通过AsyncTask从url链接抓取图像,抓取图像的函数本身工作正常。但我试图做的是将src变量传递到一个异步任务中,这似乎对我不起作用。报税表将为空 代码如下: private AsyncTask<String, Void, Drawable> task2; Drawable profile; public Drawable getProfile(String src){ task2 = new AsyncTask<Strin

大家好,我正在尝试通过AsyncTask从url链接抓取图像,抓取图像的函数本身工作正常。但我试图做的是将src变量传递到一个异步任务中,这似乎对我不起作用。报税表将为空

代码如下:

 private AsyncTask<String, Void, Drawable> task2;
 Drawable profile;
 public Drawable getProfile(String src){        
    task2 = new AsyncTask<String, Void, Drawable>() {           
        ProgressDialog dialog2;
        InputStream is;
        Drawable d;
        @Override 
        protected void onPreExecute(){
            dialog2 = new ProgressDialog(Thoughts.this, ProgressDialog.STYLE_SPINNER);
            dialog2.setMessage("Loading Data...");          
            dialog2.setCancelable(false);
            dialog2.setCanceledOnTouchOutside(false);   
            dialog2.show();
        }
        @Override
        protected Drawable doInBackground(String... src) {
                try
                {
                    is = (InputStream) new URL(src[0]).getContent();
                    d = Drawable.createFromStream(is, "src name");
                    return d;
                }catch (Exception e) {
                    e.toString();
                    return null;
                }
        }
        @Override
        protected void onPostExecute(Drawable result2) {
            profile = result2; 
            dialog2.dismiss();
        }
    };
    task2.execute(src);
    return profile;
}

AsyncTask
帮助您执行异步作业。在您的代码中,我可以看到您在调用后立即返回
Drawable
。但此时,您的asynctask尚未完成,drawable仍然为空

task2.execute(src);
return profile;
如果您想在asynctask中完成作业时设置可绘制资源,只需将
ImageView
放入您的方法中即可。应该是:

  public void getProfile(String src, final ImageView v){           

         @Override
    protected void onPostExecute(Drawable result2) {

        // set drawable for ImageView when complete.
        v.setImageDrawable(result2);
        dialog2.dismiss();
    }
    task2.excute(src);
    //do not need return anything.
  } 
使用它:

 ImageView thoughtsProfilePic =(ImageView) findViewById(R.id.ivProfilePicData);
 getProfile("http://..../xyz.jpg", thoughtsProfilePic );
希望这有帮助

更新
无法直接从异步方法返回值,这里是另一种选择。 首先,创建一个接口,以便在完成作业时通知

 public interface INotifyComplete{  
      public void onResult(Drawable result);  
 } 
那么您的活动类应该如下所示:

 public class YourActivity extends Activity implement INotifyComplete{
 private Drawable res1;
 private Drawable res2;
 public void onResult(Drawable result){
    if(result == res1){
        // do something with resource 1
        ImageView thoughtsProfilePic =(ImageView) findViewById(R.id.ivProfilePicData);
        thoughtsProfilePic.setImageDrawable(result);
    }
    if(result == res2){
        // do something with resource 2
    }
  }

 void someMethod(){
// you can use this way to call
    getProfile("http://..../xyz.jpg", res1, YourActivity.this);
    //or this
    getProfile("http://..../xyz.jpg", res2, new INotifyComplete(){
        public void onResult(Drawable result){
            // result is res2, so don't need to check
        }
    });
 }
 public void getProfile(String src, final Drawable res, final INotifyComplete notify){
   //don't need store asynctask instance
    AsyncTask<String, Void, Drawable>  task2 = new AsyncTask<String, Void, Drawable>(){

        // do something ...

        protected void onPostExecute(Drawable result2) {             
        dialog2.dismiss();
        // you will set the value to your drawable then notify it when complete job
        res = result2;
        notify.onResult(res);
    }
    }
    task2.excute();
}
  }
公共类YourActivity扩展活动实现INotifyComplete{
私人提款权1;
私人提款权2;
公开作废结果(可提取结果){
如果(结果==res1){
//用资源1做点什么
ImageView thoughtsProfilePic=(ImageView)findViewById(R.id.ivProfilePicData);
thoughtsProfilePic.setImageDrawable(结果);
}
如果(结果==res2){
//用资源2做点什么
}
}
void方法(){
//你可以用这种方式打电话
getProfile(“http://..../xyz.jpg“,res1,您的活动;
//还是这个
getProfile(“http://..../xyz.jpg“,res2,新INotifyComplete(){
公开作废结果(可提取结果){
//结果是res2,所以不需要检查
}
});
}
public void getProfile(字符串src、最终可提取res、最终INotifyComplete notify){
//不需要存储异步任务实例
AsyncTask2=新的AsyncTask(){
//做点什么。。。
受保护的void onPostExecute(可提取结果2){
对话2.解散();
//您将把该值设置为drawable,然后在完成作业时通知它
res=结果2;
通知结果(res);
}
}
任务2.excute();
}
}

在活动中编写一个公共成员函数,返回drawable,并在asyncTask类的doInBackground()方法中调用该函数

Drawable downloadImage(){
//write code here to download image so you can return any dataType
}
现在只需在doInBackground()方法中调用此函数,并将返回的结果保存在活动的某个变量中

编辑:asyncTask是您的后台线程,而不是UI线程,因此如果您想执行任何UI工作,则必须通过runOnUiThread()方法在UI线程中执行该工作


他将url传递给getprofile方法我知道你从哪里来,但如果我要填充多个imageview?哦,我刚才看到了。但是如果我想让它返回一个drawable而不是imageview。因为我需要将drawable进一步传递到另一个函数。比方说,我需要它返回一个drawable,我尝试了最终的drawable draw,但我无法设置draw的值,因为它位于一个封闭的括号或其他东西中。“我该如何解决这个问题呢?”Sam Farooq有一个很好的答案,如果你想在异步方法中返回Drawable,这里有另一个解决方案:我不太理解他的答案,他还没有回复我。试图阅读你的链接。此外,我试图在asynctask中使用for循环,但出现错误并导致应用程序崩溃。这样,从网站下载图像调用开始,UI中不会出现冻结吗?所以我在doInBackground中执行runUIThread?不,UI中不会有任何冻结,因为asyncTask是您的后台线程,asyncTask的目的是在后台执行任务,使UI保持活动状态。但当您确实想要根据长时间运行的操作的结果更改UI时,您应该在runOnUiThread方法中执行UI更改。
Drawable downloadImage(){
//write code here to download image so you can return any dataType
}
void doInBackground(){
    drawableVariable = downloadImage();    
}
runOnUiThread(new Runnable() {
           @Override
           public void run() {

               /* update your UI here for example what you are doing something */;
               profile = result2;
           }
       });