0

私のアプリが画像をオンラインでダウンロードするレイアウトに移動するたびに、デバイスがハングし、ダウンロードの完了を待つ必要があります。

私はいくつかの研究をしました。別の .NET でダウンロードすることをお勧めしますThread。しかし、ダウンロード機能を別のに実装する方法がわかりませんThread

ダウンロード画像関数を呼び出すコードは次のとおりです。

Main.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                for (j = 0; j < imagepath.length; j++) {
                    if (!imagepath[j].toString().equals("no picture")
                            && Config_GlobalFunction.isConnected()) {
                        loader = new Util_LazyLoader(imagepath[j],
                                new Util_BitmapDowloadListener() {
                                    public void ImageDownloadCompleted(
                                            Bitmap bmp) {
                                        imagebitmap[j] = bmp;
                                        invalidate();
                                    }
                                });
                        loader.run();
                    }
                }
            }
        }, 500, false);

そしてそのlazyloader

public class Util_LazyLoader implements Runnable {
String url = null;
Util_BitmapDowloadListener listener = null;

public Util_LazyLoader(String url, Util_BitmapDowloadListener listener) {
    this.url = url;
    this.listener = listener;
}

public void run() {
    Bitmap bmpImage = getImageFromWeb(url);
    listener.ImageDownloadCompleted(bmpImage);
}

private Bitmap getImageFromWeb(String url) {
    HttpConnection connection = null;
    InputStream inputStream = null;
    EncodedImage bitmap;
    byte[] dataArray = null;

    try {
        connection = (HttpConnection) (new ConnectionFactory())
                .getConnection(url + Database_Webservice.ht_params)
                .getConnection();

        int responseCode = connection.getResponseCode();
        if (responseCode == HttpConnection.HTTP_OK) {
            inputStream = connection.openDataInputStream();
            dataArray = IOUtilities.streamToBytes(inputStream);
        }
    } catch (Exception ex) {
    } finally {
        try {
            inputStream.close();
            connection.close();
        } catch (Exception e) {
        }
    }

    if (dataArray != null) {
        bitmap = EncodedImage.createEncodedImage(dataArray, 0,
                dataArray.length);
        return bitmap.getBitmap();
    } else {
        return null;
    }
}
}

ネットワークに詳しくないので、助けが必要です。

4

1 に答える 1

1

したがって、はインターフェイスUtil_LazyLoaderを実装しているため、背景画像のダウンロードをサポートするようにすでに適切に記述されていRunnableます。次のようにダウンロードを開始できます。

Util_LazyLoader loader = 
    new Util_LazyLoader(imagepath[j],
                        new Util_BitmapDowloadListener() {
                            public void ImageDownloadCompleted(final Bitmap bmp) {
                                UiApplication.getUiApplication().invokeLater(new Runnable() {
                                    public void run() {
                                        imagebitmap[j] = bmp;
                                        invalidate();
                                    }
                                });
                            }
                        });

Thread backgroundWorker = new Thread(loader);
backgroundWorker.start();

loader.run()自分 でメソッドを直接呼び出す代わりに。

Runnableクラスは、run()メソッドを持つクラスです。あなたはあなたのRunnable loaderオブジェクトを新しいものに与え、Threadそれをに伝えますstart()。これにより、UIスレッドではなく、別のスレッドでメソッドがThread実行されます。run()UIスレッドでネットワーク操作を実行しない限り、アプリがユーザーにフリーズしているように見えないようにする必要があります。

注:元のコードには、次のものがあります。

Main.getUiApplication().invokeLater(new Runnable() {
        public void run() {

おそらくそれはまったく必要ありません。そのコードがメイン(UI)スレッドから実行されている場合、実行しているのは、UIスレッドでrun()ローカルに定義されたメソッドを呼び出すようにアプリに指示することだけです。ミリ秒の遅延も通過します。多分あなたはそれが必要です(?)。ただし、すぐに実行したい場合は、上記のコード()を削除してください。(この回答の上部にある)投稿したコードを使用してを作成し、そのメソッドを呼び出します。500invokeLater(new Runnable() { public void run() { ...backgroundWorkerstart()

また、私の実装では2つのことに注意してください。

1.UiApplication.invokeLater()ビットマップを受け取ったら、このメソッドを使用しました。ネットワーク操作が完了したら、UIを更新する必要があります。ただし、これはバックグラウンドスレッドでは実行しないでください。したがって、Runnableバックグラウンドスレッドで実行するを作成し、ダウンロードが完了したらRunnable、UIを更新するために別のスレッドを作成します。

public void run() {
   imagebitmap[j] = bmp;
   invalidate();
}

2.別のを作成し、その中で変数Runnableを使用するため、パラメーターとして宣言する必要があります。コンパイラーはあなたにそれをするように要求します。別のオプションは、次の代わりにイベントロックを直接使用することです。bmpRunnablefinalinvokeLater()

public void ImageDownloadCompleted(Bitmap bmp) {
    synchronized(UiApplication.getEventLock()) {
         imagebitmap[j] = bmp;
         invalidate();
    }
}

どちらもあなたのために働くはずです。

于 2012-08-07T08:52:35.217 に答える