我无法根据以下答案从Android上的网址加载位图:https://stackoverflow.com/a/8993175/1062794
我已将案例简化为绝对最小值:
public void loadBitmap(View view) {
Bitmap b = getBitmapFromURL("http://upload.wikimedia.org/wikipedia/en/7/70/Example.png");
}
public 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;
}
}
我在清单中启用了互联网访问(我相信):
<uses-permission android:name="android.permission.INTERNET"/>
当我运行应用时,它会在尝试运行null
时崩溃并显示connection.connect()
个详细信息。单步执行我看到它试图从StrictMode.class
抛出此错误:
if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) {
throw new NetworkOnMainThreadException();
}
这是我尝试制作Android应用程序的第一天,因此我可能犯了一个明显的错误。我正在使用模拟器和Win7。
答案 0 :(得分:4)
从Android 3.0开始,无法再直接从UI线程运行同步操作。如果您尝试直接在onCreate()方法中调用loadBitmap(View视图)方法,则在运行Android 3.0及更高版本的设备上运行时,应用程序将崩溃。因为loadBitmap()方法是同步的 - 也就是说,在下载图像之前它不会返回控件 - 直接调用它会冻结您的活动的UI。 Android 3.0及更高版本不允许这样做;所有同步代码必须使用 AsyncTask 类进行包装。使用AsyncTask,您可以在单独的线程中执行后台任务,然后在UI线程中返回结果。这样,您就可以执行后台操作,而无需处理复杂的线程问题。要调用loadBitamp()方法异步,需要将代码包装在AsyncTask类的子类中,如下所示:
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
return getBitmapFromUrl(urls[0]);
}
protected void onPostExecute(Bitamp result) {
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(result);
}
}
现在在onCreate()方法中创建一个AsyncTask类的新实例并执行它:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new DownloadImage().execute("http://upload.wikimedia.org/wikipedia/en/7/70/Example.png");
}
答案 1 :(得分:2)
这是因为您尝试从ui线程访问互联网(更多信息here)。
创建一个新线程(如果你愿意,可以使用asyncTask,但任何其他线程创建方法就足够了)以便访问互联网,一旦位图准备就绪,如果你希望将它传递给ui线程显示它
另外,对于一个很好的位图处理示例,请阅读:
http://developer.android.com/training/displaying-bitmaps/index.html
答案 2 :(得分:0)
当图像大小为5 MG时,您的虚空将会崩溃。位图是堆叠RAM,因此采样20个图像* 5 = 100 mb。当你重新打开活动时,另外100 MB花费你的RAM和应用程序将崩溃。您可以在代码中添加以下行;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
options.inSampleSize = 2;
Bitmap myBitmap = BitmapFactory.decodeStream(input,rect,options);