1

スレッドを使用して画像を背景として設定していますが、このスレッドにはダイアログがあります。ダイアログが開始され、壁紙が設定されると閉じます。これが今までのコードです

setWallbtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
                new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                           // TODO Auto-generated method stub
                            WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext());
                            try {
                                image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                                wallManager.setBitmap(image);
                                Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();
                                myPd_ring.dismiss();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show();
                                myPd_ring.dismiss();
                            }
                        }
                    }, 4000);


            }
        });

したがって、ボタンをクリックするとスレッドが開始され、4 秒間ダイアログが進行状況アイコンとともに表示されます。しかし、それは正しくありません!背景を設定する時間は、4 秒を超える場合もあれば、4 秒未満になる場合もあります。したがって、4000画像を壁紙として設定するには、時間に基づいて計算する必要があります。出来ますか?

ps。多くの場合、AsyncTask を使用できませんNullPointerExceptions

4

2 に答える 2

1

質問のコードで別のスレッドを使用していないことに注意してくださいRunnable。メインの UI スレッドで実行しています。

ドキュメンテーションを見ると、AsyncTaskビットマップのデコードに を使用することをお勧めします。これは、予期しない時間がかかる可能性があるプロセスが完了した後にのみ ProgressDialog が閉じられるという、目的の結果を達成するための最良の方法でもあります。

varargsコードを正しい場所に置き、渡されたものを介して必要なものを与えるだけです。

を開始する方法は次のAsyncTaskとおりです。

    setWallbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
           new LoadImage().execute(url);
        }
    });

次に、ActivityAsyncTaskのサブクラスとして を作成します。ビットマップをダウンロードしてデコードするSingleWallネットワーク コードを に配置し、UI スレッドで実行される UI 関連のコードを に配置します。doInBackground()onPostExecute()

上記のリンクで概説されているようにWeakReference、インスタンスに a を使用することもできますが、ここではシンプルにして直接アクセスするだけにします。WallpaperManagerwallManagerAsyncTask

class LoadImage extends AsyncTask<URL, Void, Bitmap> {

    ProgressDialog myPd_ring;

    @Override
    protected void onPreExecute() {
        //Start Progress Dialog here
        myPd_ring = ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
    }

    //Runs in a background Thread
    @Override
    protected Bitmap doInBackground(URL... params) {
        URL url = params[0];
        Bitmap image = null;
        try {
            image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;
    }

    //Runs on the UI Thread
    @Override
    protected void onPostExecute(Bitmap image) {
        myPd_ring.dismiss();

        if (image == null){
            Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show();
        }
        else{
            //set image here
            try {
                SingleWall.this.wallManager.setBitmap(image);

                Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();

            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show();
            }

        }
    }
}
于 2015-05-15T19:54:38.007 に答える
0

AsyncTask を使用します。タスクの処理中に UI を更新しようとしているため、null ポインターが来る可能性があります。AsyncTask 内から次のようなものを使用する必要がある場合があります。

activity.runOnUiThread(new Runnable() {
        public void run() {
            activity.doSomeSpecialUIWork();
        }
    });
}

それがうまくいくことを願っています-それが、AsyncTask中に奇妙なnullポインターを取得していたときに解決したことです。

別の投稿の例を次に示します: runOnUiThread の使用方法

あなたの特定のコードについては、おそらくこれ:

setWallbtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                activity.runOnUiThread(new Runnable() {
                        public void run() {
                            final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true);
                           // TODO Auto-generated method stub
                            WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext());
                            try {
                                image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                                wallManager.setBitmap(image);
                                Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show();
                                myPd_ring.dismiss();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show();
                                myPd_ring.dismiss();
                            }
                        }
                    });
                }
            }
        });
于 2015-05-15T18:39:27.647 に答える