Android Picasso:方法调用应该从主线程

时间:2017-11-22 10:19:24

标签: java android picasso

我正在尝试从服务器获取信息,包括照片。我创建了一个名为ServerManager的类,它允许我下载所需的信息。但是,我无法使用Picasso下载图像,因为我得到了java.lang.IllegalStateException: Method call should happen from the main thread.

这就是我在ServerManager中所做的事情:

// Check if the photo is already downloaded
if (!checkInternalPhoto(member)) {
    final String outputURL = context.getFilesDir().getAbsolutePath() + "/" + member.photoPath;
    String photoURL = rootURL + "photos/" + member.photoPath;
    Picasso.with(context)
            .load(photoURL)
            .into(new Target() {
                @Override
                public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                    File file = new File(outputURL);
                    try {
                        file.createNewFile();
                        FileOutputStream outputStream = new FileOutputStream(file);
                        bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
                        outputStream.flush();
                        outputStream.close();
                    } catch (IOException e) {
                        Log.e("IOException",e.getLocalizedMessage());
                    }
                }
                @Override
                public void onBitmapFailed(Drawable errorDrawable) {
                }
                @Override
                public void onPrepareLoad(Drawable placeHolderDrawable) {
                }
    });
}

我该怎么办?

编辑:我尝试使用MainActivity中的代码,并收到相同的错误消息...

 public void downloadPhotos(List<Member> memberList){
    String rootInURL = serverManager.getRootURL();
    String rootOutURL = serverManager.getOutputURL();
    for(int i = 0; i < memberList.size(); i++){
        if(!serverManager.checkInternalPhoto(memberList.get(i))){
            final String outputURL = rootOutURL + memberList.get(i).photoPath;
            String photoURL = rootInURL + "photos/" + memberList.get(i).photoPath;
            Picasso.with(this)
                    .load(photoURL)
                    .into(new Target() {
                        @Override
                        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
                            File file = new File(outputURL);
                            try{
                                file.createNewFile();
                                FileOutputStream outputStream = new FileOutputStream(file);
                                bitmap.compress(Bitmap.CompressFormat.PNG,100,outputStream);
                                outputStream.flush();
                                outputStream.close();
                                Toast.makeText(context, "YEpa: " ,Toast.LENGTH_LONG).show();
                            } catch (IOException e){
                                Toast.makeText(context, "Error: " + e.toString(),Toast.LENGTH_LONG).show();
                            }
                        }

                        @Override
                        public void onBitmapFailed(Drawable errorDrawable) {

                        }

                        @Override
                        public void onPrepareLoad(Drawable placeHolderDrawable) {

                        }
                    });
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您不能从与创建该ui元素的线程不同的线程更新ui元素。在Android上,几乎总是意味着主线程。

您需要做的是将photoUrl字符串发回给您的活动或主线程上的片段。传统的方法是使用Handler。您可以在此处详细了解:https://developer.android.com/training/multiple-threads/communicate-ui.html

答案 1 :(得分:0)

尝试此操作,您的错误应消失。当您在单元Android测试中使用它时,总是会出现此问题

  

kotlin代码

 Handler(Looper.getMainLooper()).post {
 }
  

java代码

new Handler(Looper.getMainLooper()).post(() -> {
});