0

15 秒ごとに ChangeWallpaper() メソッドを呼び出す CountDownTimer があります。壁紙は正常に変更されますが、アプリを開こうとすると、App Drawer 画面が数秒間応答しなくなります。アプリが最終的に開くと、選択したすべてのものが応答するまでに 5 ~ 10 秒かかります。AsyncTask in Android Developer について読みました。これは、UI スレッドの外部でビットマップをロードし、アプリがハングしないようにすることになっていますが、機能していないようです。

次のコードは、Activity クラス内にあります。

/** changeWallpaper() **/ - called by CountDownTimer every 15 seconds
protected void changeWallpaper() throws IOException {
    Integer totalimages = finallist.size();

    if (lastloopcount == totalimages) { // if end of the list of images is reached, it resets and goes back to top.
        loopcount = 0;
        lastloopcount = 0;
    }

    for (String imagepath : finallist) { // "finallist" is global variable with all the image's paths in an array list. The Loop count is to select the next image in the array list every 15 seconds.
        loopcount++;
        if (loopcount > lastloopcount) {
            lastloopcount = loopcount;
            loopcount = 0;

            WallpaperManager wm = WallpaperManager.getInstance(this);
            wm.setBitmap(decodeImageFromPath(imagepath));

            break;
        }
    }
}

/** AsyncTask Wallpaper Load **/
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    public BitmapWorkerTask(ImageView imageView) {
        new WeakReference<ImageView>(imageView);
    }

    @Override
    protected Bitmap doInBackground(Integer... params) {
        return null;
    }
}

/** decodeImageFromPath() **/
public Bitmap decodeImageFromPath(String imagepath) {
    DisplayMetrics displayMetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    int height = displayMetrics.heightPixels;
    int width = displayMetrics.widthPixels << 2;

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imagepath, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, width, height);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(imagepath, options);
}

/** WallpaperManager (Method) **/
public static int calculateInSampleSize(
    BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // ... Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;

    int stretch_width = Math.round((float)width / (float)reqWidth);
    int stretch_height = Math.round((float)height / (float)reqHeight);

    if (stretch_width <= stretch_height) return stretch_height;
    else return stretch_width;
}
  1. AsyncTask 関数を正しく使用しましたか?
  2. これをもっと簡単に書く方法はありますか?

前もって感謝します。

編集:

/** Spinner **/
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    String chosenTime = parent.getItemAtPosition(position).toString();
    int chosenTimeNew = 0;
    if (chosenTime.contains("sec")) {
        chosenTime = chosenTime.replace(" sec","");
        chosenTimeNew = Integer.parseInt(chosenTime) * 500;
    } else if (chosenTime.contains("min") ) {
        chosenTime = chosenTime.replace(" min","");
        chosenTimeNew = Integer.parseInt(chosenTime) * 30000;
    } else if (chosenTime.contains("hour")) {
        chosenTime = chosenTime.replace(" hour","");
        chosenTimeNew = (Integer.parseInt(chosenTime) * 30000) * 60;
    } else if (chosenTime.contains("day")) {
        chosenTime = chosenTime.replace(" day","");
        chosenTimeNew = ((Integer.parseInt(chosenTime) * 30000) * 60) * 24;
    }
    rSpeed = chosenTimeNew;
}

編集2:

CountDownTimer() によって呼び出されます:

new BitmapWorkerTask(null).execute(imagepath);

それで:

    /** AsyncTask Wallpaper Load **/
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {

    public BitmapWorkerTask(ImageView imageView) {
        new WeakReference<ImageView>(imageView);
    }

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

        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        int height = displayMetrics.heightPixels;
        int width = displayMetrics.widthPixels << 2;

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(params[0], options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, width, height);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;

        Bitmap bmp = BitmapFactory.decodeFile(params[0], options);
        return bmp;
    }

    protected void onPostExecute(Bitmap bmp) {

        Context context = getApplicationContext();
        WallpaperManager wm = WallpaperManager.getInstance(context);
        try {
            wm.setBitmap(bmp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

    /** WallpaperManager (Method) **/
public static int calculateInSampleSize(
    BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // ... Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;

    int stretch_width = Math.round((float)width / (float)reqWidth);
    int stretch_height = Math.round((float)height / (float)reqHeight);

    if (stretch_width <= stretch_height) return stretch_height;
    else return stretch_width;
}
4

2 に答える 2

0

BitmapWorkerTask!も使用しません。コードに任意の部分を書き込むだけで、コードの任意の部分をバックグラウンドで実行する魔法はありませんAsyncTask。あなたもそれを使わなければなりません。

コードの長期的な部分をdoInBackground()AsyncTask のメソッドに移動し、次のように呼び出します。new BitmapWorkerTask().execute();

編集

image-path を渡すには、BitmapWorkerTask の定義を次のように変更し(Integer ではなくString... extends AsyncTask<String, Void, Bitmap> ...に注意してください)、image-path をパラメータとしてメソッドに渡します。execute()

new BitmapWorkerTask().execute(imagePath);

これは非同期で実行されるようになったため、execute() 呼び出しはすぐに返されますが、画像の読み込みにはまだ時間がかかることに注意してください。

痛みのないスレッディングの記事もお読みください。

于 2013-04-01T17:11:07.963 に答える