Android之循环队列操作

队列特性:先进先出(FIFO)——先进队列的元素先出队列。

来源于我们生活中的队列(先排队的先办完事)。

下面以一个简单的例子实现循环队列的操作。

1.新建Android应用程序

2.界面上添加按钮

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/start"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开始"/>
        <Button
            android:id="@+id/pause"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="暂停"/>
        <Button
            android:id="@+id/clear"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="清除"/>
    </LinearLayout>

    <ScrollView
		android:layout_width="match_parent"
		android:layout_height="match_parent">
	    <TextView
	        android:id="@+id/MonitorData"
	        android:layout_width="match_parent"
	        android:layout_height="wrap_content"
	        android:scrollbars="vertical"
	        android:singleLine="false"
	        android:textSize="18sp"
	        android:textStyle="normal"
	        android:textColor="#000"
			android:text="@string/hello_world"/>
	</ScrollView>

</LinearLayout>

3.处理效果

package com.sl.queuedemo;

import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

//线程发送数据入队,定时器定时处理数据
public class MainActivity extends Activity
{
	private static final String TAG = "QueueDemo";

	static final int REFRESH = 0;
	private TextView mTextView;

	public Button m_btnStart = null;
	public Button m_btnPause = null;
	public Button m_btnClear = null;
	private boolean m_bIsReading = false;

	//控制线程运行
	private boolean m_bIsRunning = false;

	//队列操作
    public int m_nWt = 0;
	public int m_nRd = 0;
	public int m_nCnt=0;
	private final byte MAX_QUEUE_SIZE	=	20;
	private final byte MAX_ELEMENT_SIZE	=	6;
	public byte m_ucMonitorData[][] = new byte[MAX_QUEUE_SIZE][MAX_ELEMENT_SIZE];

	private int nLength = 6;
	private byte TxBuffer[] = new byte[nLength];
	private byte RxBuffer[] = new byte[nLength];

	//时间操作
	private int mYear;
	private int mMonth;
	private int mDay;
	private int mHour;
	private int mMinute;
	private int mSecond;
	public String m_sMonitorTime[] = new String[MAX_QUEUE_SIZE];

	//同步设置
	private Object Mutex = new Object();

	//定时器设置
	Timer timer = new Timer();
	TimerTask task = new TimerTask()
	{
		@Override
		public void run()
		{
			Message message = new Message();
			message.what = REFRESH;
			handler.sendMessage(message);
		}
	};

	//线程处理
	@SuppressLint("HandlerLeak")
	Handler handler = new Handler()
	{
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
			case REFRESH:
				RefreshData();
				break;
			default:
				break;
			}
		}
	};

	//线程
	public Thread myThread = new Thread(new Runnable()
	{
		@Override
		public void run()
		{
			while(m_bIsRunning)
			{
				TxBuffer[0]++;
				TxBuffer[1]++;TxBuffer[1]++;
				TxBuffer[2]++;
				TxBuffer[3]++;
				TxBuffer[4]++;TxBuffer[4]++;
				TxBuffer[5]++;TxBuffer[5]++;TxBuffer[5]++;
				InQueue(TxBuffer, nLength);

				SystemClock.sleep(1000);
			}
		}
	});

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

		mTextView = (TextView)findViewById(R.id.MonitorData);

		m_btnStart = (Button)findViewById(R.id.start);
		m_btnPause = (Button)findViewById(R.id.pause);
		m_btnClear = (Button)findViewById(R.id.clear);
		m_btnStart.setOnClickListener(listener);
		m_btnPause.setOnClickListener(listener);
		m_btnClear.setOnClickListener(listener);

        m_bIsRunning = true;
        myThread.start();
		timer.schedule(task,1000,1000);
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		m_bIsRunning = false;
		timer.cancel();
		timer.purge();
	}

	public void RefreshData()
	{
		if(m_bIsReading)
		{
			String str = GetOutQueueString();
			mTextView.setText(str);
		}
	}

	OnClickListener listener = new View.OnClickListener()
	{
		@Override
		public void onClick(View v)
		{
			switch(v.getId())
			{
			case R.id.start:
				m_bIsReading = true;
				RefreshData();
				break;
			case R.id.pause:
				m_bIsReading = false;
				break;
			case R.id.clear:
				ResetQueue();
				RefreshData();
				break;
			default:
				break;
			}
		}
	};

	public void InQueue(final byte TxBuffer[],final int nLength)
	{
		synchronized (Mutex)
		{
			if(nLength<=0)
			{
				return;
			}

			//入队时间
			final Calendar c = Calendar.getInstance();
			mYear = c.get(Calendar.YEAR);
			mMonth = c.get(Calendar.MONTH) + 1;//获取的月份比实际月份小1,所以需要+1
			mDay = c.get(Calendar.DAY_OF_MONTH);
			mHour = c.get(Calendar.HOUR_OF_DAY);
			mMinute = c.get(Calendar.MINUTE);
			mSecond = c.get(Calendar.SECOND);

			String year = "0" + mYear;
			year = year.substring(year.length()-2, year.length());
			String month = "0" + mMonth;
			month = month.substring(month.length()-2, month.length());
			String day = "0" + mDay;
			day = day.substring(day.length()-2, day.length());
			String hour = "0" + mHour;
			hour = hour.substring(hour.length()-2, hour.length());
			String minute = "0" + mMinute;
			minute = minute.substring(minute.length()-2, minute.length());
			String second = "0" + mSecond;
			second = second.substring(second.length()-2, second.length());

			String str = year + "." + month + "." + day + " " + hour + ":" + minute + ":" + second + " -- ";
			m_sMonitorTime[m_nWt] = str;

			//入队数据
			for(int i =0;i<nLength;i++)
			{
				m_ucMonitorData[m_nWt][i] = TxBuffer[i];
			}
			m_nWt++;
			if(m_nWt >= MAX_QUEUE_SIZE)
			{
				m_nWt = 0;
			}
			m_nCnt++;
			if(m_nCnt > MAX_QUEUE_SIZE)
			{
				m_nCnt = MAX_QUEUE_SIZE;
				m_nRd++;
				if(m_nRd >= MAX_QUEUE_SIZE)
				{
					m_nRd = 0;
				}
			}
		}
	}

	public boolean OutQueue(byte RxBuffer[])
	{
		synchronized (Mutex)
		{
			if(m_nCnt <= 0)
			{
				return false;
			}
			for(int i=0;i<MAX_ELEMENT_SIZE;i++)
			{
				RxBuffer[i] = m_ucMonitorData[m_nRd][i];
			}
			m_nRd++;
			if(m_nRd >= MAX_QUEUE_SIZE)
			{
				m_nRd = 0;
			}
			m_nCnt--;
			return true;
		}
	}

	public String GetOutQueueString()
	{
		synchronized (Mutex)
		{
			String strline = "";
			String str = "";
			int index = m_nRd;
			for(int i=0;i<m_nCnt;i++)
			{
				strline = strline + m_sMonitorTime[index];//时间
				for(int j=0;j<MAX_ELEMENT_SIZE;j++)
				{
					strline = strline + str.format("%02X ",m_ucMonitorData[index][j]);//数据
				}
				strline = strline + "\n";//换行

				index++;
				if(index >= MAX_QUEUE_SIZE)
				{
					index = 0;
				}
			}
			return strline;
		}
	}

	public void ResetQueue()
	{
		synchronized (Mutex)
		{
			m_nCnt = 0;
			m_nWt = 0;
			m_nRd = 0;
			Log.d(TAG, "重置队列");
		}
	}
}

4.运行效果

开始运行

 

暂停运行

清除

重新开始

 

源码下载

时间: 2024-12-06 08:58:13

Android之循环队列操作的相关文章

循环队列(Circular Queue)

循环队列(Circular Queue) 1. 循环队列的概念 1.1 循环队列的定义 为了能够充分地使用数组中的存储空间,克服"假溢出"现象,可以把数组的前端和后端连接起来,形成一个环形的表,即把存储队列元素的表从逻辑上看成一个环,成为循环队列(circular queue). 1.2 循环队列中各元素的逻辑及存储关系 循环队列的首尾相接,当队头指针front和队尾指针rear进到maxSize-1后,再前进一个位置就自动到0.这可以利用除法取余的运算(%)来实现. (1)队头指针进

两种方法实现队满和队空的判断操作(循环队列)

本周的作业要求: 1.给出循环队列的存储结构定义. 2.完成循环队列的基本操作函数. 1)      初始化循环队列: 2)      建立循环队列: 3)      实现入队和出队操作: 4)     采用下面两种方法实现对满和队空的判断操作: 方法一:修改队满条件,浪费一个元素空间,队满时数组中只有一个空闲单元(必做):   方法二:设置标志flag,当front==rear且flag=0时为队空,当front==rear且flag=1时为队满(必做): 3.编写主函数实现基本操作函数功能,

循环队列的顺序存储和入队出队操作

今天看图的广度优先遍历的时候,发现用到了循环队列,补一下循环队列的知识,参考<大话数据结构>的P116~117,自己写了一个简单的测试例子便于理解. 首先需要理解以下三条公式. front是队头元素的下标,rear是队尾元素后一位的下标.(书上用头指针和尾指针,front和rear并不是指针,个人觉得不太好) 1.队列空的条件 显然front==rear 注意:如果队列不保留任何元素空间 满足front==rear的情况下,可能是队列空,也可能是队列满.所以为了方便,本文讨论的是采用保留一个元

Android 开发笔记 “Android 的消息队列模型”

Android是参考Windows的消息循环机制来实现Android自身的消息循环的. Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环). Android系统中,Looper负责管理线程的消息队列和消息循环.我们可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的Looper对象. 一个线程可以存在(当然也可以不存

Android 的消息队列模型

Android 的消息队列模型 Android是参考Windows的消息循环机制来实现Android自身的消息循环的.    Android通过Looper.Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环).     Android系统中,Looper负责管理线程的消息队列和消息循环.我们可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的Loo

多线程与循环队列

多线程使用循环队列其实也不是个很难的东西,在工作中遇到了一个队列行为非常古怪,怎么也想不通,一直都没有认证对待这些,有点怵,所以这回想认真对待一下. 多线程使用循环队列主要就是要避免两个线程同时操作队列,加个锁就可以很容易的实现,win32中用临界区就可以做到. 代码: // CirQueue.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <Wi

数据结构Java实现07----队列:顺序队列&amp;顺序循环队列、链式队列、顺序优先队列

数据结构Java实现07----队列:顺序队列&顺序循环队列.链式队列.顺序优先队列 一.队列的概念: 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作. 队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头.队列的插入操作通常称作入队列,队列的删除操作通常称作出队列. 下图是一个依次向队列中插入数据元素a0,a1,...,an-

(一)循环队列

队列可以使用数组或者链表实现,这里介绍一种使用数组实现的循环队列. 所谓循环队列,是指当尾指针超过数组索引界限时,通过取余运算返回数组起始端,只要保证尾指针和头指针不相遇,就可以继续存储元素. 首先设定队列的大小,并建立队列结构体: #define MAXSIZE 100001 typedef struct { int items[MAXSIZE]; int front; int rear; }Queue; 设头指针和尾指针指向同一索引时队列为空,起始时均在索引0处. void initQueu

09.循环队列与链队列

一.队列与循环队列 1.队列 (1)队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表.队列是一种先进先出(Fiirst In First Out)的线性表,简称FIFO.允许插入的一端称为队尾,允许删除的一端称为队头. 从队列的定义可知,队列的入队操作,其实就是在队尾追加一个元素,不需要移动任何元素,因此时间复杂度为O(1).队列的删除操作,与栈不同的是,队列元素的出列是在队头,即小标为0的位置,若要删除一个元素的话,需要移动队列的所有元素,因此事件复杂度为O(n).