生产者消费者模型 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到请求队列中