简体   繁体   English

Android如何每秒运行一次AsyncTask?

[英]Android How to run an AsyncTask every second?

I'm new in Android and not really knowing how to deal this problem: I have an AsyncTask which reads a position (X,Y,Z) from a XML file. 我是Android的新手,并不真正知道如何处理此问题:我有一个AsyncTask,它从XML文件读取位置(X,Y,Z)。 As this position changes every second, I want, after I push a button (called with "StartListener") to read and draw every new position CONTINUOUSLY and stop reading it when I press the button again... 当此位置每秒变化时,我希望在按下按钮(用“ StartListener”调用)之后连续读取并绘制每个新位置,并在再次按下按钮时停止读取它...
Somebody can help me? 有人可以帮助我吗? - Here is a part of my MainActivity -这是我MainActivity的一部分

(For the moment my app reads and draws a position only when I press the button...) (目前我的应用仅在按下按钮时读取并绘制位置...)

      private OnClickListener StartListener = new OnClickListener() {

          @Override
          public void onClick(View v) {

                TextView ButText = (TextView)findViewById(R.id.buttonStart);

                 String value=ButText.getText().toString();
                 if(value.equals("Start positioning")){
                     ButText.setText("Stop positioning");

                     new PositionAsync().execute(); //read data from XML file

                 }
                 else if(value.equals("Stop positioning")){
                     ButText.setText("Start positioning");
                     //new PositionAsync().cancel(true);
                 }              
            }                   
      }; // END LISTENER START BUTTON


// READ XML FILE
class PositionAsync extends AsyncTask<Void, Void, Void> {

    XMLHelper helper;
    @Override
    protected Void doInBackground(Void... arg0) {
        helper = new XMLHelper();
        helper.get();
        return null;
    }   

    @Override
    protected void onPostExecute(Void result) {         

        Paint paintBlack = new Paint(); paintBlack.setAntiAlias(true); paintBlack.setColor(Color.BLACK);

        BitmapFactory.Options myOptions = new BitmapFactory.Options();
        myOptions.inDither = true;
        myOptions.inScaled = false;
        myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
        myOptions.inPurgeable = true;
        File ImageSource = new File("/sdcard/app_background3.jpg");
        Bitmap bitmap2 = BitmapFactory.decodeFile(ImageSource.getAbsolutePath(),myOptions);         
        Bitmap workingBitmap = Bitmap.createBitmap(bitmap2);
        Bitmap mutableBitmap2 = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);

        Canvas canvas2 = new Canvas(mutableBitmap2);

        float RoomWidthPx = canvas2.getWidth();
        float RoomHeightPx = canvas2.getHeight();
        float RoomXmeter = (float) 9.3;
        float RoomZmeter = (float) 14.7;

        for (PositionValue position : helper.positions) {

            String PosX = position.getPositionX(); String PosY = position.getPositionY(); String PosZ = position.getPositionZ();

            float x = Float.valueOf(PosX); float y = Float.valueOf(PosY); float z = Float.valueOf(PosZ);

            float xm = x*RoomWidthPx/RoomXmeter; 
            float zm = z*RoomHeightPx/RoomZmeter;

            canvas2.drawCircle(xm, zm, 25, paintBlack);

            ImageView imageView = (ImageView)findViewById(R.id.imageView1);
            imageView.setAdjustViewBounds(true);
            imageView.setImageBitmap(mutableBitmap2);

            // SAVE DRAWINGS INTO FILE
            FileOutputStream fos = null;
            try {
            fos = new FileOutputStream ("/sdcard/app_background3.jpg");
            mutableBitmap2.compress (Bitmap.CompressFormat.JPEG, 95, fos); 
            } catch (Throwable ex) {ex.printStackTrace (); }    
        };

    }
} //END READ XML FILE

you can use Handlers to deal with this: 您可以使用处理程序来处理此问题:

private boolean isBusy = false;//this flag to indicate whether your async task completed or not
private boolean stop = false;//this flag to indicate whether your button stop clicked
private Handler handler = new Handler();

public void startHandler()
{
    handler.postDelayed(new Runnable()
    {

        @Override
        public void run()
        {
            if(!isBusy) callAysncTask();

            if(!stop) startHandler();
        }
    }, 1000);
}

private void callAysncTask()
{
    //TODO
    new PositionAsync().execute();
}

set isBusy to true when the async task in doInBackground and set it back to false in the last line of onPostExecute. doInBackground中的异步任务时将isBusy设置为true,并在onPostExecute的最后一行将其设置为false。

when you click stop button set stop to true, when click start button set stop to false 当您单击停止按钮将stop设置为true时,当单击开始按钮将stop设置为false时

I think you are doing too many task in just one second. 我认为您在短短一秒钟内完成了太多任务。 You could, instead, prepare all heavy staff in the onPreExecute() of the AsyncTask, read the XML and do the painting in the doInBackground() , resfresh the ImageView in the onProgressUpdate() and finally, when the task is done, save the image to the sdcard . 相反,您可以在AsyncTask的onPreExecute()中准备所有繁重的工作人员,读取XML并在doInBackground()中进行绘制,在onProgressUpdate()刷新ImageView,最后,完成任务后,保存映像到sdcard

I've modified your Asynctask to accomplish the above scenario, I've not tested it but it gives you the idea. 我已经修改了您的Asynctask来完成上述方案,但我并未对其进行测试,但它为您提供了思路。

In the onCreate() method of your activity you start the AsyncTask just once. 在活动的onCreate()方法中,只需启动AsyncTask一次。 It stays executing or sleeping until you set the Quit_Task variable to true. 在您将Quit_Task变量设置为true之前,它将保持执行或休眠状态。 When the button is pressed you toggle the variable Do_Drawing: Do_Drawing=!Do_Drawing; 当按下按钮时,切换变量Do_Drawing: Do_Drawing=!Do_Drawing; and that's it. 就是这样。

private boolean Do_Drawing = false;
private boolean Quit_Task = false;

// READ XML FILE
class PositionAsync extends AsyncTask<Void, Void, Void>
{
    Paint paintBlack;
    BitmapFactory.Options myOptions;
    Bitmap mutableBitmap2;
    Canvas canvas2;
    XMLHelper helper;

    void Sleep(int ms)
    {
        try
        {
            Thread.sleep(ms);
        }
        catch (Exception e)
        {
        }
    }

    @Override
    protected void onPreExecute()
    {
        // Prepare everything for doInBackground thread
        paintBlack = new Paint();
        paintBlack.setAntiAlias(true);
        paintBlack.setColor(Color.BLACK);
        myOptions = new BitmapFactory.Options();
        myOptions.inDither = true;
        myOptions.inScaled = false;
        myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
        myOptions.inPurgeable = true;
        File ImageSource = new File("/sdcard/app_background3.jpg");
        Bitmap bitmap2 = BitmapFactory.decodeFile(ImageSource.getAbsolutePath(), myOptions);
        Bitmap workingBitmap = Bitmap.createBitmap(bitmap2);
        mutableBitmap2 = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
        canvas2 = new Canvas(mutableBitmap2);
        helper = new XMLHelper();
    }

    @Override
    protected Void doInBackground(Void... arg0)
    {
        while (!Quit_Task)
        {
            // Sleep until button is pressed or quit
            while (!Do_Drawing)
            {
                Sleep(1000);
                if (Quit_Task)
                    return null;
            }

            float RoomWidthPx = canvas2.getWidth();
            float RoomHeightPx = canvas2.getHeight();
            float RoomXmeter = (float) 9.3;
            float RoomZmeter = (float) 14.7;
            // keep drawing until button is pressed again or quit
            while (Do_Drawing)
            {
                if (Quit_Task)
                    return null;
                helper.get();
                for (PositionValue position : helper.positions)
                {
                    String PosX = position.getPositionX();
                    String PosY = position.getPositionY();
                    String PosZ = position.getPositionZ();

                    float x = Float.valueOf(PosX);
                    float y = Float.valueOf(PosY);
                    float z = Float.valueOf(PosZ);

                    float xm = x * RoomWidthPx / RoomXmeter;
                    float zm = z * RoomHeightPx / RoomZmeter;

                    canvas2.drawCircle(xm, zm, 25, paintBlack);
                }
                this.publishProgress((Void) null);
                Sleep(1000);
            }
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Void... progress)
    {
        // once all points are read & drawn refresh the imageview
        try
        {
            ImageView imageView = (ImageView) findViewById(R.id.imageView1);
            imageView.setAdjustViewBounds(true);
            imageView.setImageBitmap(mutableBitmap2);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPostExecute(Void result)
    {
        // SAVE DRAWINGS INTO FILE once the task is done.
        FileOutputStream fos = null;
        try
        {
            fos = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "app_background3.jpg");
            mutableBitmap2.compress(Bitmap.CompressFormat.JPEG, 95, fos);
        }
        catch (Throwable ex)
        {
            ex.printStackTrace();
        }
    }
} // END READ XML FILE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM