生产者消费者模型 android

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

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

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

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

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

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

二.任务请求对象:

package com.example.baize.touchdelegate.producer;

import java.util.LinkedList;

/**
 * 事件对象
* <p>
* 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;

/**
 * 生产游戏手柄的按键事件,本线程通过打断与启动标志来停止线程
* <p>
* 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;

/**
 * 游戏手柄按键不停的产生事件,由此类进行代理并采用生产者消费者模式实现
* <p>
* 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到请求队列中

猜你喜欢

转载自www.cnblogs.com/Awangzhen/p/8922183.html