【问题标题】:java.lang.IllegalStateException: Method call should not happen from the main thread with piccasojava.lang.IllegalStateException:方法调用不应该从带有毕加索的主线程发生
【发布时间】:2016-08-04 08:30:50
【问题描述】:

我试图在用户登录时创建一个用户对象并将其保存在共享首选项中。用户对象具有我从 json 对象中检索的姓名和姓氏,以及我试图用 piccaso 获取的位图配置文件图片(图片的行也在 json 对象中)。在这两种情况下,我都尝试使用 volley 和 asynctask 进行尝试。

我的用户模型:

public class User{

    private String name,lastName;
    private Bitmap profilePicture;
    Context context;

    public User(JSONObject object , Context context){
        this.context = context;

        try {
            this.name = object.getString("firstName");
            this.lastName = object.getString("lastName");
            this.profilePicture = Picasso.with(context).load(object.getString("image")).get();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

还有我的截击请求:

  JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {

                            Intent intent = new Intent(LoginActivityScreen.this, HomeActivityScreen.class);

                            SharedPreferences.Editor editor = preferences.edit();

                            RoomateModel model = new RoomateModel(response, context);


                            Gson gson = new Gson();
                            String json = gson.toJson(model);
                            editor.putString("USER", json);
                            editor.commit();


                            startActivity(intent);


                        }

                    }

【问题讨论】:

    标签: java android picasso


    【解决方案1】:

    基本上是NetworkOnMainThreadException的封装。

    你需要检查你在哪里调用 User(...) 构造函数,因为它们有这一行:

    this.profilePicture = Picasso.with(context).load(object.getString("image")).get();
    

    有效地进行远程调用以从object.getString("image") URL 检索图片。确保调用在非 UI 线程上执行。这是使用 Picasso 的主要优势,因为它确保网络处理和数据缓冲在一个线程内完成,并且在 Android UI 元素 (ImageView) 内膨胀资源(图像)是在 UI 线程上完成的,无需任何额外的努力来自图书馆的用户。

    或者,您可以尝试使用毕加索的Target 接口:

    Picasso.with(context).load(object.getString("image").into(new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            //This gets called when your application has the requested resource in the bitmap object
            User.this.profilePicture = bitmap;
        }
    
        @Override
        public void onBitmapFailed(Drawable errorDrawable) {
            //This gets called if the library failed to load the resource
        }
    
        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {
            //This gets called when the request is started
        }
    });
    

    【讨论】:

    • 我尝试在 asynctask 中从 doInBackground() 调用它,但我遇到了同样的异常。 @NitroNbg
    • 检查编辑以查看替代方案。但是,我不建议发出异步调用,即使在对象的构造函数中使用回调也是如此。您可以在User 对象中仅存储个人资料图片的String (URL),然后在您即将在应用程序中显示该用户的图片时发出Piccasso.with(context).load(user.getProfilePicture()).into(imageView)
    • 但是这样我每次创建homeActivity时都需要加载图片
    • 好吧,我不了解您的应用程序的架构和设计,但缓存资源是另一个问题,我们需要更多详细信息来帮助您。
    • 我想解释一下。我在侧边菜单标题中有一个图像视图,我想在家庭活动中的 onCreate() 方法中对其进行初始化。所以第一次用户登录时,我想创建一个用户对象并将其保存在 sharedprefrences 中,这样每次创建 homeActvity 时,我都会从该对象获取图像
    【解决方案2】:

    尝试在代码加载图像之前添加这部分

    if (android.os.Build.VERSION.SDK_INT > 9) {
                StrictMode.ThreadPolicy policy =
                        new StrictMode.ThreadPolicy.Builder().permitAll().build();
                    StrictMode.setThreadPolicy(policy);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-11
      • 2018-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多