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 秒!因此,4000应该以将图像设置为墙纸的时间为基础进行计算。是否可以?

附言。我不能使用 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将下载和解码Bitmap的网络代码放入doInBackground()其中,然后将UI相关代码放入onPostExecute(),在UI线程上运行。

请注意,您也可以使用WeakReference实例WallpaperManager,如上面链接中所述,但我会在这里保持简单,直接访问wallManager,如果AsyncTask是您的 Activity 的子类,您可以这样做。

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。您可能需要在 AsyncTask 中使用类似的东西:

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

希望有效 - 这就是我在 AsyncTask 期间收到奇怪的空指针时为我解决的问题。

这是另一篇文章的示例:如何使用 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 回答