android 实现一个按钮按下时总触发一个事件

一.简单的思路为:生产者+消费者模式来实现

1.重写这个对象的触摸事件(对触摸事件与事件分发机制的同学不了解的可以查阅其他资料)

2.在MotionEvent.ACTION_DOWN:事件中启动一个线程,这个线程类似生产者,它不停的生产想要的事件

这里的事件为了调用的顺序,建议采用队列的方式来缓存,事件对象可任意

3.在MptionEvent.ACTION_UP:事件中取消这个线程,取消线程即停止这个线程,采用置中断标记来停止一个线程

5.从任务队列中取出任务进行执行,类似消费者,代码模式与生产者很类似,具体的思路可参看我的前几编文章,里面有很详细的生产者消费者模式多线程的运用


二.任务请求对象:

package com.example.baize.touchdelegate.producer;

import java.util.LinkedList;

/**
 * 事件对象
 * 

* Created by lxb on 2017/3/31. */ public class EventRequest<T> { private LinkedList<T> requestQueue = new LinkedList<>(); private int count; // 任务队列请求数 public EventRequest() { this.count = 0; } public synchronized void buildEvent(T request) throws InterruptedException { while (!requestQueue.isEmpty() && count >= requestQueue.size()) { wait(); } System.out.println(Thread.currentThread().getName() + "正在产生" + request + "到请求队列中"); requestQueue.addLast(request); count++; notifyAll(); } public synchronized T sendEvent() throws InterruptedException { while (count <= 0) { wait(); } T request = requestQueue.pop(); count--; notifyAll(); System.out.println(Thread.currentThread().getName() + "已经成功从请求队列中拿到" + request); return request; } }


三.生产者线程:

package com.example.baize.touchdelegate.producer;

/**
 * 生产游戏手柄的按键事件,本线程通过打断与启动标志来停止线程
 * 

* Created by lxb on 2017/3/31. */ public class ProduceEventThread<T> extends Thread { private EventRequest<T> eventRequest; private volatile boolean terminated = false; // 停止请求标志 private T type; //事件请求类型 public ProduceEventThread(T type, EventRequest<T> eventRequest) { this.eventRequest = eventRequest; this.type = type; } public void run() { while (!terminated) { try { this.eventRequest.buildEvent(type); } catch (InterruptedException e) { terminated = true; } } } public void cancel(){ terminated = true; interrupt(); } }

四.消费者线程:

package com.example.baize.touchdelegate.producer;

/**
 * 发送游戏手柄事件的线程,类似消费者
 *
 * Created by lxb on 2017/3/31.
 */

public class SendEventThread<T> extends Thread {


    private EventRequest<T> eventRequest;

    private volatile boolean terminated = false; // 停止请求标志

    private T type;       //事件请求类型

    public SendEventThread(T type, EventRequest<T> eventRequest) {

        this.eventRequest = eventRequest;
        this.type = type;
    }

    public void run() {
        while (!terminated) {

            try {
                this.eventRequest.sendEvent();
            } catch (InterruptedException e) {
                terminated = true;
            }

        }
    }

    public void cancel(){
        terminated = true;
        interrupt();
    }
}

五。整个触摸对象的触摸事件代理类:

package com.example.baize.touchdelegate;

import android.view.MotionEvent;
import android.view.View;

import com.example.baize.touchdelegate.producer.EventRequest;
import com.example.baize.touchdelegate.producer.ProduceEventThread;
import com.example.baize.touchdelegate.producer.SendEventThread;

/**
 * 游戏手柄按键不停的产生事件,由此类进行代理并采用生产者消费者模式实现
 * 

* Created by lxb on 2017/3/31. */ public class TouchEventDelegate<T> implements View.OnTouchListener { private T type ; private ProduceEventThread<T> produceEventThread; private SendEventThread<T> sendEventThread; private EventRequest<T> eventRequest; public TouchEventDelegate(T type) { this.type = type; eventRequest = new EventRequest<>(); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startThreads(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: stopAllThreads(); break; } return true; } private void startThreads() { produceEventThread = new ProduceEventThread<>(type, eventRequest); sendEventThread = new SendEventThread<>(type, eventRequest); produceEventThread.start(); sendEventThread.start(); } private void stopAllThreads() { if (produceEventThread != null) { produceEventThread.cancel(); produceEventThread = null; } if (sendEventThread != null) { sendEventThread.cancel(); sendEventThread = null; } } }



调用方式:

package com.example.baize.activity;

import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.baize.R;
import com.example.baize.touchdelegate.TouchEventDelegate;
import com.example.baize.utils.VibrateUtils;

/**
 * 游戏手柄
 * Created by lxb on 2017/3/31.
 */

public class GameCtrlActivity extends BaseActivity{

    private ImageView mBack;
    private ImageView mLeft;
    private ImageView mRight;
    private ImageView mUp;
    private ImageView mDown;

    private ImageView mFun1;
    private ImageView mFun2;
    private ImageView mFun3;
    private ImageView mFun4;
    private ImageView mFun5;

    private ImageView mX;
    private ImageView mY;
    private ImageView mA;
    private ImageView mB;

    private static final Integer leftTouch = 101;
    private static final Integer upTouch = 102;
    private static final Integer rightTouch = 103;
    private static final Integer downTouch = 104;
    private static final String xTouch = "X";
    private static final String yTouch = "Y";
    private static final String aTouch = "A";
    private static final String bTouch = "B";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game_ctrl);
        initView();
    }

    @Override
    protected void setStatusBar() {
    }


    private void initView(){
        EventClick click = new EventClick();

        mBack = getView(R.id.gc_back);
        mLeft = getView(R.id.gc_left);
        mRight = getView(R.id.gc_right);
        mUp = getView(R.id.gc_up);
        mDown = getView(R.id.gc_down);

        mFun1 = getView(R.id.gc_fun1);
        mFun2 = getView(R.id.gc_fun2);
        mFun3 = getView(R.id.gc_fun3);
        mFun4 = getView(R.id.gc_fun4);
        mFun5 = getView(R.id.gc_fun5);

        mX = getView(R.id.gc_x);
        mY = getView(R.id.gc_y);
        mA = getView(R.id.gc_a);
        mB = getView(R.id.gc_b);


        mBack.setOnClickListener(click);

        /*mLeft.setOnClickListener(click);
        mRight.setOnClickListener(click);
        mUp.setOnClickListener(click);
        mDown.setOnClickListener(click);*/

        mFun1.setOnClickListener(click);
        mFun2.setOnClickListener(click);
        mFun3.setOnClickListener(click);
        mFun4.setOnClickListener(click);
        mFun5.setOnClickListener(click);

       /* mX.setOnClickListener(click);
        mY.setOnClickListener(click);
        mA.setOnClickListener(click);
        mB.setOnClickListener(click);*/

        mLeft.setOnTouchListener(new TouchEventDelegate<>(leftTouch));
        mUp.setOnTouchListener(new TouchEventDelegate<>(upTouch));
        mRight.setOnTouchListener(new TouchEventDelegate<>(rightTouch));
        mDown.setOnTouchListener(new TouchEventDelegate<>(downTouch));

        mX.setOnTouchListener(new TouchEventDelegate<>(xTouch));
        mY.setOnTouchListener(new TouchEventDelegate<>(yTouch));
        mA.setOnTouchListener(new TouchEventDelegate<>(aTouch));
        mB.setOnTouchListener(new TouchEventDelegate<>(bTouch));




    }

    private class EventClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {

            VibrateUtils.vSimple(GameCtrlActivity.this, 100);

            switch(v.getId()){

                case R.id.gc_back:
                    GameCtrlActivity.this.finish();
                    break;

                case R.id.gc_fun1:
                case R.id.gc_fun2:
                case R.id.gc_fun3:
                case R.id.gc_fun4:
                case R.id.gc_fun5:
                    Toast.makeText(GameCtrlActivity.this,"未定义",Toast.LENGTH_SHORT).show();
                    break;

            }
        }
    }



}

测试结果:

04-01 09:11:16.727 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.727 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.732 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.732 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.733 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.733 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.733 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.740 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中





你可能感兴趣的:(android,按钮按下时总是执行一个事,android,java并发编程)