1

この回答に基づいて、Android の URL からビットマップをロードする際に問題があります: 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を使用しています。

4

3 に答える 3

4

Android 3.0 以降では、同期操作を UI スレッドから直接実行できなくなりました。onCreate() メソッドで loadBitmap(View 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");
}
于 2013-01-05T23:51:55.527 に答える
2

これは、UI スレッドからインターネットにアクセスしようとしているためです (詳細はこちら)。

インターネットにアクセスするために新しいスレッドを作成し(必要に応じて asyncTask を使用できますが、他のスレッド作成方法で十分です)、ビットマップの準備ができたら、表示したい場合はそれを ui スレッドに渡します

また、ビットマップ処理の素敵なサンプルについては、これを読んでください:

http://developer.android.com/training/displaying-bitmaps/index.html

于 2013-01-05T23:34:49.177 に答える
0

画像サイズが 5 MG になると、ボイドがクラッシュします。ビットマップは RAM をスタックしているため、サンプル 20 画像 * 5 = 100 mb です。アクティビティを再度開くと、RAM をさらに 100 MB 消費し、アプリがクラッシュします。次の行をコードに追加します。

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inPreferredConfig = Config.RGB_565;
                options.inSampleSize = 2;
                Bitmap myBitmap = BitmapFactory.decodeStream(input,rect,options);
于 2013-09-30T10:28:31.883 に答える