1

im trying to create a user object when the user log in and save it in shared prefrences. the user object has name and last name which im retreiving from json object and a bitmap profile pic which im trying to get with piccaso (the line to the picture is also in the json object). i tryed it with volley and with asynctask in both cases i get the expeption.

my user model:

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();
        }
    }

and my volley request:

  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);


                        }

                    }
or am-shalem
  • 47
  • 1
  • 10

2 Answers2

2

Basically it's an encapsulation of NetworkOnMainThreadException.

You need to check where you're calling User(...) constructors since they have this line:

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

Which effectively does a remote call to retrieve picture from object.getString("image") URL. Make sure that call is executed on a non-UI thread. That's the main advantage of using Picasso because it makes sure that the network handling and data buffering is done inside one thread, and inflating the resource (image) inside Android UI element (ImageView) is done on the UI thread without any extra effort from the user of the library.

Alternatively, you can try using Picasso's Target interface:

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
    }
});
nstosic
  • 2,584
  • 1
  • 17
  • 21
  • 1
    i tried calling it from doInBackground() in an asynctask i had the same exception. @NitroNbg – or am-shalem Aug 04 '16 at 08:50
  • 1
    Check the edit to see an alternative. However I do not recommend issuing an asynchronous call, even with a callback inside the object's constructor. You can store just a `String` (URL) of the profile picture in your `User` object and then issue `Piccasso.with(context).load(user.getProfilePicture()).into(imageView)` when you're about to display that user's picture in the application. – nstosic Aug 04 '16 at 08:56
  • but this way i need to load the picture every time the homeActivity is created – or am-shalem Aug 04 '16 at 09:15
  • Well, I have no knowledge of the architecture and the design of your app but caching the resource is another issue and we need more details to help you. – nstosic Aug 04 '16 at 09:28
  • ill try to explain. i have an image view inside the side menu header which i want to initialize at onCreate() method in home activity. so the 1st time the user login i want to create an user object and save it in sharedprefrences so that every time the homeActvity is created i get the image from this object – or am-shalem Aug 04 '16 at 09:57
  • i forgot to tag you in the last comment @NitroNbg – or am-shalem Aug 04 '16 at 16:52
  • If you're set on keeping `User` data in `SharedPreferences` you cannot save drawable resource, but you can save its *Base64* representation which can effectively be equivalent since you can also decode it using Android SDK. See ariefbayu's response http://stackoverflow.com/a/8586244/2150044 or open a new question please. – nstosic Aug 05 '16 at 09:22
-1

Try to add this part before code to load image

if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy policy =
                    new StrictMode.ThreadPolicy.Builder().permitAll().build();
                StrictMode.setThreadPolicy(policy);
}
sonnv1368
  • 1,547
  • 12
  • 17