-1

I am working on an Android App where I am trying to decode InputStream to Bitmap .

Bitmap bmp = BitmapFactory.decodeStream(s);

Above line inside QBContent.downloadFileTask(...) throwing NetworkOnMainThread exception.

Here is the reference code :

getView() of ChatAdapter

      @Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    QBChatMessage chatMessage = getItem(position);
    LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    int type = getItemViewType(position);
    if (convertView == null) {
        convertView = vi.inflate(R.layout.list_item_image, parent, false);
        holder = createViewHolder(convertView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    QBUser currentUser = ChatService.getInstance().getCurrentUser();
    boolean isOutgoing = chatMessage.getSenderId() == null || chatMessage.getSenderId().equals(currentUser.getId());
    setAlignment(holder, isOutgoing);

    Collection<QBAttachment> attachments = chatMessage.getAttachments();
    //attachments.
    if (attachments != null && attachments.size() > 0) {

        String imageid = "";
        for (QBAttachment attachment : attachments) {
            imageid = attachment.getId();
        }

        final int imageid1 = Integer.parseInt(imageid);

        QBContent.downloadFileTask(imageid1, new QBEntityCallbackImpl<InputStream>() {
            @Override
            public void onSuccess(InputStream inputS, Bundle params) {

                if (inputS != null) {
                    Bitmap bmp = BitmapFactory.decodeStream(inputS);
                    Drawable d = new BitmapDrawable(context.getResources(), bmp);
                    if (holder.image_attachment != null)
                        holder.image_attachment.setImageDrawable(d);
                }
            }
            @Override
            public void onError(List<String> errors) {
                Log.d("Image Download Error : ", errors.toString());
            }
        }, new QBProgressCallback() {
            @Override
            public void onProgressUpdate(int progress) {
            }
        });
    } 
    return convertView;
}

What wrong I am doing here ? Help me please .

Shishupal Shakya
  • 1,632
  • 2
  • 18
  • 41

4 Answers4

2

Try this

private class SampleAsync extends AsyncTask<Void, Void, Bitmap> {

    @Override
    protected Bitmap doInBackground(Void... params) {
        // your background code fetch InputStream
        InputStream s = //your inputstream ;
        Bitmap bmp = BitmapFactory.decodeStream(s);
        return bmp;
    }

    @Override
    protected void onPostExecute(Bitmap bmp) {
        super.onPostExecute(bmp);
        if(bmp != null){
            Drawable d = new BitmapDrawable(context.getResources(), bmp);
            if(holder.image_attachment != null)
                holder.image_attachment.setImageDrawable(d);
        }
    }
}
Jigar Shekh
  • 2,800
  • 6
  • 29
  • 54
0

Do the same inside the doInbackground method and do the actions inside a UI thread

Sreyas
  • 744
  • 1
  • 7
  • 25
0

You are indirectly you are calling network on main thread as adapters are used to update ui and they run on main thread. To solve it either move complete code with adapter to another asyncTask or remove your asynctask call from adapter.

Vivek Mishra
  • 5,669
  • 9
  • 46
  • 84
0

Finally I got the answer .

1 . Removed the AsyncTask and called QBContent.downloadFileTask(...) directly.

2 . Modified QBContent.downloadFileTask(...) . Here I have decoded InputStream to BitMap in a Background thread , Previously I was doing it in UI thread .

QBContent.downloadFileTask(imageid1, new QBEntityCallbackImpl<InputStream>() {
            @Override
            public void onSuccess(final InputStream inputS, Bundle params) {

                if (inputS != null) {
                    new Thread() {
                        public void run() {
                            final Bitmap bmp = BitmapFactory.decodeStream(inputS);
                            try {
                                context.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        Drawable d = new BitmapDrawable(context.getResources(), bmp);
                                        if (holder.image_attachment != null)
                                            holder.image_attachment.setImageDrawable(d);
                                    }
                                });
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }.start();
                }

            }

            @Override
            public void onError(List<String> errors) {
                Log.d("Image Download Error : ", errors.toString());

            }
        }, new QBProgressCallback() {
            @Override
            public void onProgressUpdate(int progress) {

            }
        });
Shishupal Shakya
  • 1,632
  • 2
  • 18
  • 41
  • Very bad solution. Start programming in a normal way and remove that StrintMode statement. – greenapps Jan 05 '16 at 11:14
  • @greenapps then help me plz , I dont know any other way . – Shishupal Shakya Jan 05 '16 at 11:16
  • What happens if you remove the StrintMode call? – greenapps Jan 05 '16 at 11:17
  • It is giving NetworkonMainThreadException while decoding inputstream to Bitmap . – Shishupal Shakya Jan 05 '16 at 11:18
  • Please edit your post so we can see the code you use now. Remove all irrelevant code. Or maybe add another code block to show your new code. – greenapps Jan 05 '16 at 11:20
  • 1
    What is this `QBContent.downloadFileTask()` ? You did not post the code. Is it originally for a Java application? It seems not suitable for Android as onSucces() has an InputStream parameter. onSuccess() will be executed on the main thread so you cannot read from that -network- stream in onSuccess to begin with. – greenapps Jan 05 '16 at 11:58
  • @greenapps I have removed StrictMode . So I think I have found a good solution now . Plz remove your first comment , very bad solution :) – Shishupal Shakya Jan 05 '16 at 12:07
  • `Modified QBContent.downloadFileTask`. No you did not. You added a thread to your code in onSucces() to read from the input stream. So you only start the download in onSucces. Strange and wrong. Much better would be to do the download in the `QBContent.downloadFileTask`it self and change onSucces to have a Bitmap parameter. There should be only succes after downloading the file and having a bitmap. – greenapps Jan 05 '16 at 12:10
  • @greenapps Can you please post your comment as an answer , and a right code snippet for QBContent.downloadFileTask(...) so that I can understand more clearly . – Shishupal Shakya Jan 05 '16 at 12:14
  • First please explain why you use QBContent.downloadFileTask(...). It looks not suitable for android. If you only need to download an image from the internet and convert to a Bitmap you could much better use an AsyncTask and HttpUrlConnection. – greenapps Jan 05 '16 at 12:18
  • @greenapps See , I am working on a chat application , Here I am trying to send attachment ( image ), for this I am using QuickBlox Sdk . So here I am using QuickBlox api to download image from QuickBlox Server . And QBContent.downloadFileTask() is the part of QuickBlox Api . Here I am using imageid to download image . – Shishupal Shakya Jan 05 '16 at 12:25
  • Is that QB API for Android? – greenapps Jan 05 '16 at 12:26
  • Since I am using imageid So I can't use AsyncTask and HttpUrlConnection . – Shishupal Shakya Jan 05 '16 at 12:27
  • Here is the link : http://quickblox.com/developers/SimpleSample-content-android#Download_file – Shishupal Shakya Jan 05 '16 at 12:28
  • I cannot comment on that as you did not post the code for `downloadFileTask()` so we cannot see what url is used. Tell us the url and if GET or POST is used. – greenapps Jan 05 '16 at 12:28
  • It's the QuickBlox api method downloadFileTask() . So I need to debug code . I am doing it .Plz wait . – Shishupal Shakya Jan 05 '16 at 12:31
  • `SimpleSample-content-android`. Well you saw that it does not work in Android whithout using a thread to read from the inputstream. I wonder what they mean with `success`. A succesfull connection? – greenapps Jan 05 '16 at 12:31
  • Yes , this is a misleading doc. I am really frustated . – Shishupal Shakya Jan 05 '16 at 12:35
  • It takes file id only , I have seen no url , no GET and POST . – Shishupal Shakya Jan 05 '16 at 12:38
  • Ok it takes a file id. But what is done with that id? And how is an input stream opened and onSuccess called with that input stream as parameter? – greenapps Jan 05 '16 at 12:40
  • I have tried for this exercise earlier for the same problem , But it is very confusing . – Shishupal Shakya Jan 05 '16 at 12:42
  • Well ok. Meanwhile i think that you found a workable solution that keeps as close as possible to QuickBlox. – greenapps Jan 05 '16 at 12:45
  • Yes , Thanks for your amazing help . – Shishupal Shakya Jan 05 '16 at 12:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/99817/discussion-between-android-dev-and-greenapps). – Shishupal Shakya Jan 05 '16 at 12:51