计算时间线程android

Calculate time thread android

我正在使用线程将图像设置为背景,并且在该线程中我有一个对话框。对话框启动并应在设置墙纸时关闭。这是目前的代码

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 应该根据将图像设置为墙纸的时间进行计算。可能吗?

ps。我不能使用 AsyncTask 因为我得到很多 NullPointerExceptions

使用 AsyncTask,可能会出现空指针,因为您正试图在任务处理期间更新 UI。您可能需要在 AsyncTask 中使用类似这样的东西:

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

希望有用 - 这就是我在 AsyncTask 期间遇到奇怪的空指针时解决问题的方法。

这是来自另一个 post 的示例:how to use 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();
                            }
                        }
                    });
                }
            }
        });

请注意,您没有将单独的线程与问题中的代码一起使用,您是 运行 主 UI 线程上的 Runnable

如果您查看 the documentation,建议使用 AsyncTask 解码位图,这也是实现您想要的结果的最佳方式,其中 ProgressDialog 仅在处理后才被关闭已完成,这可能需要花费不可预测的时间。

您只需要将代码放在正确的位置,并通过传入的 varargs 提供所需的内容。

以下是您应该如何开始 AsyncTask:

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

然后,创建 AsyncTask 作为 SingleWall Activity 的子 class。 将网络代码放在doInBackground()中,它将下载并解码Bitmap,然后将UI相关代码放在onPostExecute()中,它在UI线程上运行。

请注意,您还可以对 WallpaperManager 实例使用 WeakReference,如上文 link 中所述,但我将在此处保持简单,只需访问 wallManager 直接,如果 AsyncTask 是 Activity.

的子 class,则可以这样做
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();
            }

        }
    }
}