0

サーバーから画像を取得し、そのファイルをアプリの背景として使用しようとしています。そのためには AsyncTask を使用する必要があることは既に知っていますが、アプリを実行するとまだクラッシュまたはフリーズします。

私が使用するコードは次のとおりです。

AsyncTask を呼び出すには:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Intent BG = new Intent((Intent) DownloadBGTask.THREAD_POOL_EXECUTOR);

AsyncTask:

import java.net.URL;

import com.pxr.tutorial.json.Getbackground;

import android.os.AsyncTask;

public class DownloadBGTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Getbackground.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        // Things to be done while execution of long running operation
    }

    protected void onPostExecute(Long result) {
        // xecution of result of Long time consuming operation
    }
}

Getbackground.java:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.os.Environment;

public class Getbackground {
    URL url;

    public static long downloadFile(URL url2) {
    try {

        URL url = new URL ("http://oranjelan.nl/oranjelan-bg.png");
        InputStream input = url.openStream();{
        try {

            File fileOnSD=Environment.getExternalStorageDirectory();    
            String storagePath = fileOnSD.getAbsolutePath();
            OutputStream output = new FileOutputStream (storagePath + "/oranjelangbg.png");
                try {

                    byte[] buffer = new byte[1000000];
                    int bytesRead = 0;
                    while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
                    output.write(buffer, 0, bytesRead);
                    }
                    } finally {
            output.close();
            }
            } catch (IOException e) {
            throw new RuntimeException(e);
    } finally {
        try {
            input.close();
            } catch (IOException e) {
            throw new RuntimeException(e);
     }
   }    
 }    
        } catch (MalformedURLException ex) {
         throw new RuntimeException(ex);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }

        return 0;
    }
}

PS、くだらないコードで申し訳ありません。私はこれに本当に慣れていないので、本当にばかげた間違いがあったとしても驚かないでください。

4

2 に答える 2

3

あなたのコメントは、この行にぶら下がっていると言っているので:

Intent BG = new Intent((Intent) DownloadBGTask.THREAD_POOL_EXECUTOR);

それから始めましょう。

あなたは初心者のように聞こえるかもしれませんが (恥ずべきことではありません!)、このタスクを並行して実行する必要は必ずしもないと思います。

AsyncTask に関する Android のドキュメントを読むと、彼らはあなたをそれから遠ざけようとします:

実行順序

最初に導入されたとき、AsyncTasks は単一のバックグラウンド スレッドでシリアルに実行されました。DONUT 以降、これはスレッドのプールに変更され、複数のタスクが並行して動作できるようになりました。HONEYCOMB 以降、並列実行によって発生する一般的なアプリケーション エラーを回避するために、タスクは単一のスレッドで実行されます。

本当に並列実行が必要な場合は、THREAD_POOL_EXECUTOR を使用して executeOnExecutor(java.util.concurrent.Executor, Object[]) を呼び出すことができます。

したがって、単に url または url のリストをタスクに渡して順番に (一連の) 実行する場合は、次のようにタスクを開始します。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DownloadBGTask downloader = new DownloadBGTask();
    downloader.execute(new URL("http://www.google.com"), 
                       new URL("http://stackoverflow.com"));

文字列は、取得する URL です (1 つまたは複数の場合があります)。タスクのメソッドexecute()に渡されるパラメーター。doInBackground()


編集:タスクの開始を過ぎたように見えるので、ここにいくつかの他の提案があります:

  1. 1000000 バイトは大きなバッファのように思えます。私はそれがうまくいかないと言っているわけではありませんが、私は通常のようなものを使用しますbyte[1024].

  2. ダウンロードを保存するディレクトリについて。これは私が使用したいコードです:

private File mDownloadRootDir;
private Context mParent;        // usually this is set to the Activity using this code

private void callMeBeforeDownloading() {
    // http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
    mDownloadRootDir = new File(Environment.getExternalStorageDirectory(),
        "/Android/data/" + mParent.getPackageName() + "/files/");
    if (!mDownloadRootDir.isDirectory()) {
        // this must be the first time we've attempted to download files, so create the proper external directories
        mDownloadRootDir.mkdirs();
    }
}

以降

storagePath = mDownloadRootDir.getAbsolutePath();
于 2012-07-09T09:58:22.507 に答える
1

このユーティリティメソッドを使用して、GetBackgroundクラスのWebから画像をダウンロードします。

// Utiliy method to download image from the internet
    static private Bitmap downloadBitmap(String url) throws IOException {
        HttpUriRequest request = new HttpGet(url.toString());
        HttpClient httpClient = new DefaultHttpClient();
        HttpResponse response = httpClient.execute(request);

        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();
        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            byte[] bytes = EntityUtils.toByteArray(entity);

            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
                    bytes.length);
            return bitmap;
        } else {
            throw new IOException("Download failed, HTTP response code "
                    + statusCode + " - " + statusLine.getReasonPhrase());
        }
    }

そしてあなたの DownloadBGTask extends AsyncTask<URL, Integer, Bitmap>

URL url = new URL ("http://oranjelan.nl/oranjelan-bg.png");
DownloadBGTask task = new DownloadBGTask(); 
task.execute(url);
于 2012-07-09T09:19:38.330 に答える