在NetworkOnMainThreadException中将url转换为位图

时间:2016-02-09 06:11:10

标签: android url bitmap

我想将某些URL中的图像动态添加到线性布局中。运行该段代码时出现错误无法启动活动

  

ComponentInfo:android.os.NetworkOnMainThreadException at   com.example.star.example.CompinfoActivity.getBitmapFromURL(CompinfoActivity.java:70)               在com.example.star.example.CompinfoActivity.insertPhoto(CompinfoActivity.java:50)               在com.example.star.example.CompinfoActivity.onCreate(CompinfoActivity.java:38)

请帮忙。这是我下面活动的代码。

public class CompinfoActivity extends AppCompatActivity {

Dialog dialog;
LinearLayout myGallery;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_compinfo);

    dialog = new Dialog(this);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(R.layout.activity_compinfopopup);
    dialog.getWindow().getAttributes().width = AbsListView.LayoutParams.MATCH_PARENT;
    dialog.getWindow().getAttributes().height = AbsListView.LayoutParams.WRAP_CONTENT;
    dialog.show();

    myGallery = (LinearLayout) dialog.findViewById(R.id.mygallery);
    myGallery.addView(insertPhoto("http://example.com/a.png"));
    myGallery.addView(insertPhoto("http://example.com/b.png"));
    myGallery.addView(insertPhoto("http://example.com/c.png"));
    myGallery.addView(insertPhoto("http://example.com/d.png"));
    new MyTask().execute();



}

View insertPhoto(String path){
    Bitmap bm;
    bm =  getBitmapFromURL(path);
    LinearLayout layout = new LinearLayout(getApplicationContext());
    layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
    layout.setGravity(Gravity.CENTER);

    ImageView imageView = new ImageView(getApplicationContext());
    imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageView.setImageBitmap(bm);

    layout.addView(imageView);
    return layout;
}


public static Bitmap getBitmapFromURL(String src) {
    try {
        URL url = new URL(src);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

7 个答案:

答案 0 :(得分:7)

只需按照以下方式执行操作 -

public class MyAsync extends AsyncTask<Void, Void, Bitmap>{

    @Override
    protected Bitmap doInBackground(Void... params) {

        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            return myBitmap;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

    }
}

现在从url访问位图,如下所示 -

MyAsync obj = new MyAsync(){

        @Override
        protected void onPostExecute(Bitmap bmp) {
            super.onPostExecute(bmp);

            Bitmap bm = bmp;
            LinearLayout layout = new LinearLayout(getApplicationContext());
            layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
            layout.setGravity(Gravity.CENTER);

            ImageView imageView = new ImageView(getApplicationContext());
            imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setImageBitmap(bm);

            layout.addView(imageView);
        }
    };

然后最终执行AsynTask -

obj.execute();

答案 1 :(得分:1)

你不应该在主线程中像ankit那样进行任何网络调用。你在OnCreate()方法中写了所有内容。使用AsyncTask代替。

我建议您使用排球NetworkImageViewUniversal Image loader

直接从服务器显示图像。

答案 2 :(得分:0)

试试这个

URL url = new URL("http://....");
Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream()); 

只需将您的网址替换为我工作

答案 3 :(得分:0)

您无法在UI主线程上进行任何网络调用。像下面一样实现AsyncTask并调用

new LoadImage(imageView).execute()

异步任务实现::

class LoadImage extends AsyncTask<Object, Void, Bitmap>{

    private ImageView imv;
    private String path;

    public LoadImage(ImageView imv) {
         this.imv = imv;
         this.path = imv.getTag().toString();
    }

@Override
protected Bitmap doInBackground(Object... params) {
    Bitmap bitmap = null;
    File file = new File( 
            Environment.getExternalStorageDirectory().getAbsolutePath() + path);

    if(file.exists()){
        bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
    }

    return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
    if (!imv.getTag().toString().equals(path)) {
           /* The path is not same. This means that this
              image view is handled by some other async task. 
              We don't do anything and return. */
           return;
    }

    if(result != null && imv != null){
        imv.setVisibility(View.VISIBLE);
        imv.setImageBitmap(result);
    }
}

}

答案 4 :(得分:0)

要在应用中显示图片,将其下载到存储中,然后显示它们正常工作

您将通过搜索有关如何下载文件,编写OnDownloadCompleteListener来获得答案

每次下载照片时重新加载imageView。

答案 5 :(得分:0)

更改insertPhoto(String path)方法,如下所示:

View insertPhoto(String path){   
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setLayoutParams(new AbsListView.LayoutParams(250, 250));
layout.setGravity(Gravity.CENTER);

ImageView imageView = new ImageView(getApplicationContext());
imageView.setLayoutParams(new AbsListView.LayoutParams(220, 220));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);    

  //Download and display image
        new AsyncTask<String, Void, Bitmap>(){


            @Override
            protected Bitmap doInBackground(String... urls) {
                 String url = urls[0];

                Bitmap mIcon11 = null;
                try {


                   HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                   connection.setDoInput(true);
                   connection.connect();
                   InputStream input = connection.getInputStream();
                   mIcon11 = BitmapFactory.decodeStream(input);



                } catch (Exception e) {
                    Log.e("Error for image ", e.getMessage());
                    e.printStackTrace();
                    mIcon11 = null;
                }
                return mIcon11;
            }


            protected void onPostExecute(Bitmap result) {
                if(result!= null){
                    imageView.setImageBitmap(null);
                    imageView.setImageBitmap(result);                       

                }

            }
        }.execute(path);

layout.addView(imageView);
return layout;

}

希望这有帮助。

答案 6 :(得分:0)

调用此方法将Url转换为android

中的Bitmap
public static Bitmap getBitmapFromURL(String url) {
        try {
            URL url = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap bitmapFrmUrl = BitmapFactory.decodeStream(input);
            return bitmapFrmUrl;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

别忘了在AndroidManifest.xml中添加INTERNET权限