Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/184.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按住Android按钮可连续循环一个方法_Android_Button - Fatal编程技术网

按住Android按钮可连续循环一个方法

按住Android按钮可连续循环一个方法,android,button,Android,Button,我有一个按钮,我设置了一个ontouchlistener来连续执行一个方法,但当我按住按钮时,它在一次方法调用后停止执行 我的方法基本上是从2到4连续循环 下面是我的代码片段 broadcastButton = (Button) findViewById(R.id.broadcastButton); broadcastButton.setText("Loop"); broadcastButton.setOnTouchListener(new View.OnTouchListener() {

我有一个按钮,我设置了一个ontouchlistener来连续执行一个方法,但当我按住按钮时,它在一次方法调用后停止执行

我的方法基本上是从2到4连续循环

下面是我的代码片段

broadcastButton = (Button) findViewById(R.id.broadcastButton);
broadcastButton.setText("Loop");
broadcastButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        broadcastmode = 1;
                        schedulePeriodicMethod();
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        broadcastmode = 0;
                        stopPeriodicMethod();


                }
                return true;
            }
        });

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
    }

    public void stopPeriodicMethod() {
        exHandler.removeCallbacks(execution);
    }

    private Runnable execution = new Runnable() {
        @Override
        public void run() {
            connectDevice(flag);
            serialSend("C");
            flag++;
            if (flag > 4)
                flag = 2;
        }
    };
需要帮助说明我哪里做错了,程序没有循环

我认为schedulePeriodicMethod;将调用此一次:

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
}
postDelayed将运行一次,因此需要从方法本身调用它

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
        schedulePeriodicMethod();
}
我认为计划周期法;将调用此一次:

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
}
postDelayed将运行一次,因此需要从方法本身调用它

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
        schedulePeriodicMethod();
}
这是因为MotionEvent.ACTION\u DOWN和MotionEvent.ACTION\u同时移动火。按下按钮时,请使用此方法

MOVE_THRESHOLD_DP = 20 * getActivity().getResources()
                .getDisplayMetrics().density;
    @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    final int action = event.getAction();
                    switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        Log.d("TAG", "ON Down" + onMoveOccur);
                        onMoveOccur = false;
                        mDownPosX = event.getX();
                        mDownPosY = event.getY();

                      //your code 
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.d("TAG", "ON UP==" + onMoveOccur);

                        if (!onMoveOccur) {
                            //your code 
                        }
                        break;

                    case MotionEvent.ACTION_MOVE:
                        if (Math.abs(event.getX() - mDownPosX) > MOVE_THRESHOLD_DP
                                || Math.abs(event.getY() - mDownPosY) > MOVE_THRESHOLD_DP) {
                            onMoveOccur = true;
                        }
                        break;

                    default:
                        break;
                    }

                    return false;
                }
            });
这是因为MotionEvent.ACTION\u DOWN和MotionEvent.ACTION\u同时移动火。按下按钮时,请使用此方法

MOVE_THRESHOLD_DP = 20 * getActivity().getResources()
                .getDisplayMetrics().density;
    @Override
                public boolean onTouch(View v, MotionEvent event) {
                    // TODO Auto-generated method stub
                    final int action = event.getAction();
                    switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        Log.d("TAG", "ON Down" + onMoveOccur);
                        onMoveOccur = false;
                        mDownPosX = event.getX();
                        mDownPosY = event.getY();

                      //your code 
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.d("TAG", "ON UP==" + onMoveOccur);

                        if (!onMoveOccur) {
                            //your code 
                        }
                        break;

                    case MotionEvent.ACTION_MOVE:
                        if (Math.abs(event.getX() - mDownPosX) > MOVE_THRESHOLD_DP
                                || Math.abs(event.getY() - mDownPosY) > MOVE_THRESHOLD_DP) {
                            onMoveOccur = true;
                        }
                        break;

                    default:
                        break;
                    }

                    return false;
                }
            });

删除线程休眠,因为它在这里什么都不做,最多会使应用跳过6帧,最坏的情况下甚至会使一些设备崩溃,因为它会使主线程停止100毫秒

try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
让shadulePeriodicMethod称之为“自我”

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
        if (broadcastmode == 1){
            schedulePeriodicMethod();
        }
}

删除线程休眠,因为它在这里什么都不做,最多会使应用跳过6帧,最坏的情况下甚至会使一些设备崩溃,因为它会使主线程停止100毫秒

try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
让shadulePeriodicMethod称之为“自我”

public void schedulePeriodicMethod() {
        exHandler.postDelayed(execution, 100);
        if (broadcastmode == 1){
            schedulePeriodicMethod();
        }
}

将起始函数从

public void schedulePeriodicMethod() {
    exHandler.postDelayed(execution, 100);
}

您的runnable可以:

private Runnable execution = new Runnable() {
    @Override
    public void run() {
        if (broadcastmode ==0) return;
        connectDevice(flag);
        serialSend("C");
        flag++;
        if (flag > 4)
            flag = 2;
        //call the runnable itself again, to keep execution going
        exHandler.postDelayed(execution, 100);
    }
};

而且,正如斯加尔所说,你的Thread.sleep是完全无用的。顺便说一句,Android中的Thread.sleep不是一个好的实践,尤其是在UI线程上

public void schedulePeriodicMethod() {
    exHandler.postDelayed(execution, 100);
}

您的runnable可以:

private Runnable execution = new Runnable() {
    @Override
    public void run() {
        if (broadcastmode ==0) return;
        connectDevice(flag);
        serialSend("C");
        flag++;
        if (flag > 4)
            flag = 2;
        //call the runnable itself again, to keep execution going
        exHandler.postDelayed(execution, 100);
    }
};

而且,正如SGal所说,你的Thread.sleep是完全无用的。顺便说一句,Android中的Thread.sleep不是一个好的实践,尤其是在UI线程上

//create a handler, override handle message of Handler
    private Handler myHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {

// do yo stuffs here like UI update etc. 

//create a new message since a message will be consumed once as it       //delivered by handler after the delay
    Message message = new Message();
    message.what = msg.what;
// send the new message with handler
    myHandler.sendMessageDelayed(message, 150);
// 150 is time in milliseconds after which handler will give callback
    }
    };
//让我们在触摸视图时调用处理程序,将ontouch listener设置为//所需的视图 //在触摸视图时,创建一条新消息,并将其//传递给处理程序

 @Override
    public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
    Message message = new Message();
    myHandler.sendMessage(message);
    break;

// on action up of on touch of the view, remove the messages and call backs
//case MotionEvent.ACTION_UP:
    myHandler.removeCallbacksAndMessages(null);
    break;
    }
    return false;
    }

下面是连续循环方法的简单方法

//create a handler, override handle message of Handler
    private Handler myHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {

// do yo stuffs here like UI update etc. 

//create a new message since a message will be consumed once as it       //delivered by handler after the delay
    Message message = new Message();
    message.what = msg.what;
// send the new message with handler
    myHandler.sendMessageDelayed(message, 150);
// 150 is time in milliseconds after which handler will give callback
    }
    };
//让我们在触摸视图时调用处理程序,将ontouch listener设置为//所需的视图 //在触摸视图时,创建一条新消息,并将其//传递给处理程序

 @Override
    public boolean onTouch(View v, MotionEvent event) {
    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
    Message message = new Message();
    myHandler.sendMessage(message);
    break;

// on action up of on touch of the view, remove the messages and call backs
//case MotionEvent.ACTION_UP:
    myHandler.removeCallbacksAndMessages(null);
    break;
    }
    return false;
    }

尝试调用方法本身。当我按下按钮尝试调用方法本身时,应用程序崩溃。当我再次按下按钮尝试调用该方法时,应用程序崩溃。当我按下按钮时,应用程序崩溃。您可以发布stacktrace PLZOFSource!我真傻。postDelayed未阻塞,可能会出现堆栈溢出异常。你应该从runnable中调用该方法,但是我看到@Apollo已经发布了正确的答案。我尝试再次调用该方法,一旦我按下按钮,应用程序就会崩溃。你可以发布stacktrace plzofcource!我真傻。postDelayed未阻塞,可能会出现堆栈溢出异常。你应该从runnable调用这个方法,但是我看到@Apollo已经发布了正确的答案。这种方法有效。谢谢它执行得太快了,所以我把执行间隔调大了。但是,如果在再次执行/循环之前需要等待某个事件触发,我该如何做呢?在回调时设置一个条件。但是如果你有多个循环条件,也许你并不真的需要一个循环,而是一个想要的执行?因此,只要在需要时删除recall&call schedulePeriodicMethod即可。这种方法有效。谢谢它执行得太快了,所以我把执行间隔调大了。但是,如果在再次执行/循环之前需要等待某个事件触发,我该如何做呢?在回调时设置一个条件。但是如果你有多个循环条件,也许你并不真的需要一个循环,而是一个想要的执行?因此,只要在需要时删除recall&call schedulePeriodicMethod即可。