当前位置: 编程技术>移动开发
本页文章导读:
▪剔除list的数据 删除list的数据
转载:
http://www.cnblogs.com/luxh/archive/2012/05/19/2509314.html
http://developer.51cto.com/art/201205/339130.htm
list转换成Iterator
http://topic.csdn.net/u/20090605/16/8459f033-142d-4144-a5fd-a2c41156567e.html
.........
▪ Can't create handler inside thread that has not called Looper.prepare() 错误有关问题 Can't create handler inside thread that has not called Looper.prepare() 异常问题
产生该问题原因:
1. 在线程中调用handler的sendMessage方法
2。AsyncTask中的doInBackground方法不可直接操作UI
解决方.........
▪ Netty的一些札记 Netty的一些笔记
Netty的一些笔记 1. 仍然要说明一点,netty仍然是一个nio,其开发者与mina是同一个人,可以认为时mina的升级版和改进版吧。 2. 其实对nio框架的编程的,我已经不是太热衷,.........
[1]剔除list的数据
来源: 互联网 发布时间: 2014-02-18
删除list的数据
转载:
http://www.cnblogs.com/luxh/archive/2012/05/19/2509314.html
http://developer.51cto.com/art/201205/339130.htm
list转换成Iterator
http://topic.csdn.net/u/20090605/16/8459f033-142d-4144-a5fd-a2c41156567e.html
昨天一位项目组同事需要在ArrayList中删除所有不等于指定值的元素,但是她弄了很久,发现总是删得不完全。刚好我以前做过类似的功能,就告诉她是因为ArrayList删除元素后长度变小了,元素的索引也会跟着改变,但是迭代的下标没有跟着相应的改变的缘故。
/** * 删除Arraylist中值为"c"的元素 */ public static void main(String[] args) { List<String> list = new ArrayList<String>(); //"c"在Arraylist不连续存储 /* list.add("c"); list.add("a"); list.add("c"); list.add("b"); list.add("c"); list.add("d"); list.add("c"); */ //"c"在Arraylist有连续存储 list.add("a"); list.add("c"); list.add("c"); list.add("b"); list.add("c"); list.add("c"); list.add("d"); list.add("c"); //删除Arraylist中值为"c"的元素 //有可能不能全部删除 //removeListElement1(list); //能够正确删除 //removeListElement2(list); //能够正确删除 //removeListElement3(list); } /** * 删除list中值为"c"的元素 * * 这种方式: * * 当值为"c"的元素在Arraylist中不连续存储的时候,是可以把值为"c"的元素全部删掉 * * 但是当值为"c"的元素在Arraylist中有连续存储的时候,就没有把值为"c"的元素全部删除 * 因为删除了元素,Arraylist的长度变小了,索引也会改变,但是迭代的下标没有跟着变小 */ public static void removeListElement1(List<String> list) { for(int i=0;i<list.size();i++) { if("c".equals(list.get(i))) { list.remove(i); } } } /** * 删除Arraylist中值为"c"的元素 * * 这种方式: * * 不管值为"c"的元素在Arraylist中是否连续,都可以把值为"c"的元素全部删除 */ public static void removeListElement2(List<String> list) { for(int i=0;i<list.size();i++) { if("c".equals(list.get(i))) { list.remove(i); --i;//删除了元素,迭代的下标也跟着改变 } } } /** * 删除Arraylist中值为"c"的元素 * * 这种方式: * * 不管值为"c"的元素在list中是否连续,都可以把值为"c"的元素全部删除 * * 需保证没有其他线程同时在修改 */ public static void removeListElement3(List<String> list) { Iterator<String> iterator = list.iterator(); while(iterator.hasNext()) { String str = iterator.next(); if("c".equals(str)) { iterator.remove(); } } }
[2] Can't create handler inside thread that has not called Looper.prepare() 错误有关问题
来源: 互联网 发布时间: 2014-02-18
Can't create handler inside thread that has not called Looper.prepare() 异常问题
产生该问题原因:
1. 在线程中调用handler的sendMessage方法
2。AsyncTask中的doInBackground方法不可直接操作UI
解决方法:
在调用handler的方法前执行Looper.prepare()。Looper用于封装了android线程中的消息循环,默认情况下一个线程是不存在消息循环(message loop)的,需要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用
例:class LooperThread extends Thread
{ public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); }
因为activity的主线程是自己创建消息队列的,所以在Activity中新建Handler时,不需要先调用Looper.prepare()。
[3] Netty的一些札记
来源: 互联网 发布时间: 2014-02-18
Netty的一些笔记
Netty的一些笔记
1. 仍然要说明一点,netty仍然是一个nio,其开发者与mina是同一个人,可以认为时mina的升级版和改进版吧。
2. 其实对nio框架的编程的,我已经不是太热衷,毕竟就是使用一个工具而已,因为熟悉了nio的编程模式,发现这些框架都是千篇一律,只不过看看谁封装得好,效率更高而已。其实自己实现一个nio框架也未尝是件难事,但是我相信,写到最后,你会发现你写的和这些框架也肯定类似,重复造轮子不说,估计还没有别人写得好。
3. 写这篇博客的目的,如果我以后要用netty再编程时,使用api更方便些,方便来查找看看。
1. ServerSocket的bind流程
(1) ServerSocketChannel.open()-->之后fireChannelOpen,向上流(一般处理ServerSocket的配置信息);
(2)fireChannelOpen中调用chanel的bind方法-->bind事件(向下流)(,socket.socket().bind处理具体的绑定工作,之后触发fireChannelBound;若是执行
socket.close(),则触发fireChannelUnbound,fireChannelClosed,向上流
2. 处理Socket
(1)创建一个新的ChannelPipeline对象与之关联;
(2)创建实例NioAcceptedSocketChannel,触发fireChannelOpen,fireChannelBound,fireChannelConnected事件
(3)注册到NioWorker
(4)fireChannelBound,fireChannelConnected
3. buffer说明
(1) 用两个变量维持buffer的可读,可写的内容
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
| | (CONTENT) | |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
初始值:
readerIndex=0;
wirterIndex=0;
可以读的大小: readerIndex---(writerIndex - 1), 都是包含
可写的内容: writerIndex--(capacity-1), 都是包含
丢弃的内容(Discardable bytes)-->处理已经读过的内容, 通过调用discardReadBytes() 方法丢弃, 其实执行了一个System.arrayCopy的操作.
BEFORE discardReadBytes()
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
AFTER discardReadBytes()
+------------------+--------------------------------------+
| readable bytes | writable bytes (got more space) |
+------------------+--------------------------------------+
| | |
readerIndex (0) <= writerIndex (decreased) <= capacity
netty中的字节拷贝,底层刚刚读取到的-->ChannelBuffer是零字节拷贝的;
但是ChannelBuffer-->解码器的数据处理,这个一般来说是有字节拷贝的。
4. 读取数据
(1)Bytebuffer读取到并转换为ChannelBuffer,之后触发fireMessageReceived
(2)用一个累积的ChannelBuffer读取,这个buffer是公用的, 每次读取前, 若这个Buffer已经读取了数据(一般是进行了累积),则先discardReadBytes()丢掉
已经处理过得的数据;否则第一次读取直接传递原始的ChannelBuffer,这样若第一次就可以处理完,则避免了字节的复制,更高效,否则就将数据放到缓冲区里。
(3)注意ChannelBuffer是动态分配大小的,一个channel有一个,那么要注意这个的大小,避免过大的问题。
5. 写数据,
(1)先将数据放到一个写的队列中
(2)进行输出。
6. 多线程处理事件
(1)使用ExecutionHandler,只是加入了多线程机制,进行异步处理,之后仍然是调用之后的处理器进行处理。
(2)事件的调度策略完全在于Executors的实现。
(3)MemoryAwareThreadPoolExecutor只是简单的提交任务,变成异步处理而已,增加内存的控制
(4)OrderedMemoryAwareThreadPoolExecutor保证来自同一个channel的事件A一定执行完后才执行事件B(即保证一个channel的执行顺序),但是同一个channel的所有事件
是否应该固定在同一个线程中执行,这个则没有必要。
实现的关键:ConcurrentMap<Object, Executor>, 就是一个channel,对应一个执行器,这个执行器在真正工作线程中被调度执行。
(4.1)执行器里有一个队列,保证来自同一个channel的事件都添加到里面;
(4.2)执行器执行时,依次取出事件任务进行执行。
7. 客户端的处理
(1)Boss线程,单独的负责连接的请求
(1.1)创建NioClientSocketChannel对象;先创建SocketChannel(并且调用open方法),并预先分配一个worker--》 fireChannelOpen(this);--》执行bind方法
socket().bind(localAddress),fireChannelBound(channel, channel.getLocalAddress());--》 ch.connect(remoteAddress)连接远程地址;
(1.2)具体的处理都在NioClientSocketPipelineSink类里,针对连接进行一下说明,若见建立成功,则直接扔给worker线程处理;若建立失败,则扔给boss线程处理(因为是非阻塞的,
可能一开始会建立不成功)。
(2)worker线程,负责处理建立成功的连接
8. SSL
(1)客户端, SSLHandler放在位置1, 触发握手开始的操作放到最后一个Handler的channelConnected中,
客户端握手过程(handshake):
1. beginHandshake, 执行代理任务(就是ssl会话过程中的一些计算);
2. 输出数据到服务端wrapNonAppData(这时没应用数据);
3. 检查握手状态;
Netty的一些笔记
1. 仍然要说明一点,netty仍然是一个nio,其开发者与mina是同一个人,可以认为时mina的升级版和改进版吧。
2. 其实对nio框架的编程的,我已经不是太热衷,毕竟就是使用一个工具而已,因为熟悉了nio的编程模式,发现这些框架都是千篇一律,只不过看看谁封装得好,效率更高而已。其实自己实现一个nio框架也未尝是件难事,但是我相信,写到最后,你会发现你写的和这些框架也肯定类似,重复造轮子不说,估计还没有别人写得好。
3. 写这篇博客的目的,如果我以后要用netty再编程时,使用api更方便些,方便来查找看看。
1. ServerSocket的bind流程
(1) ServerSocketChannel.open()-->之后fireChannelOpen,向上流(一般处理ServerSocket的配置信息);
(2)fireChannelOpen中调用chanel的bind方法-->bind事件(向下流)(,socket.socket().bind处理具体的绑定工作,之后触发fireChannelBound;若是执行
socket.close(),则触发fireChannelUnbound,fireChannelClosed,向上流
2. 处理Socket
(1)创建一个新的ChannelPipeline对象与之关联;
(2)创建实例NioAcceptedSocketChannel,触发fireChannelOpen,fireChannelBound,fireChannelConnected事件
(3)注册到NioWorker
(4)fireChannelBound,fireChannelConnected
3. buffer说明
(1) 用两个变量维持buffer的可读,可写的内容
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
| | (CONTENT) | |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
初始值:
readerIndex=0;
wirterIndex=0;
可以读的大小: readerIndex---(writerIndex - 1), 都是包含
可写的内容: writerIndex--(capacity-1), 都是包含
丢弃的内容(Discardable bytes)-->处理已经读过的内容, 通过调用discardReadBytes() 方法丢弃, 其实执行了一个System.arrayCopy的操作.
BEFORE discardReadBytes()
+-------------------+------------------+------------------+
| discardable bytes | readable bytes | writable bytes |
+-------------------+------------------+------------------+
| | | |
0 <= readerIndex <= writerIndex <= capacity
AFTER discardReadBytes()
+------------------+--------------------------------------+
| readable bytes | writable bytes (got more space) |
+------------------+--------------------------------------+
| | |
readerIndex (0) <= writerIndex (decreased) <= capacity
netty中的字节拷贝,底层刚刚读取到的-->ChannelBuffer是零字节拷贝的;
但是ChannelBuffer-->解码器的数据处理,这个一般来说是有字节拷贝的。
4. 读取数据
(1)Bytebuffer读取到并转换为ChannelBuffer,之后触发fireMessageReceived
(2)用一个累积的ChannelBuffer读取,这个buffer是公用的, 每次读取前, 若这个Buffer已经读取了数据(一般是进行了累积),则先discardReadBytes()丢掉
已经处理过得的数据;否则第一次读取直接传递原始的ChannelBuffer,这样若第一次就可以处理完,则避免了字节的复制,更高效,否则就将数据放到缓冲区里。
(3)注意ChannelBuffer是动态分配大小的,一个channel有一个,那么要注意这个的大小,避免过大的问题。
5. 写数据,
(1)先将数据放到一个写的队列中
(2)进行输出。
6. 多线程处理事件
(1)使用ExecutionHandler,只是加入了多线程机制,进行异步处理,之后仍然是调用之后的处理器进行处理。
(2)事件的调度策略完全在于Executors的实现。
(3)MemoryAwareThreadPoolExecutor只是简单的提交任务,变成异步处理而已,增加内存的控制
(4)OrderedMemoryAwareThreadPoolExecutor保证来自同一个channel的事件A一定执行完后才执行事件B(即保证一个channel的执行顺序),但是同一个channel的所有事件
是否应该固定在同一个线程中执行,这个则没有必要。
实现的关键:ConcurrentMap<Object, Executor>, 就是一个channel,对应一个执行器,这个执行器在真正工作线程中被调度执行。
(4.1)执行器里有一个队列,保证来自同一个channel的事件都添加到里面;
(4.2)执行器执行时,依次取出事件任务进行执行。
7. 客户端的处理
(1)Boss线程,单独的负责连接的请求
(1.1)创建NioClientSocketChannel对象;先创建SocketChannel(并且调用open方法),并预先分配一个worker--》 fireChannelOpen(this);--》执行bind方法
socket().bind(localAddress),fireChannelBound(channel, channel.getLocalAddress());--》 ch.connect(remoteAddress)连接远程地址;
(1.2)具体的处理都在NioClientSocketPipelineSink类里,针对连接进行一下说明,若见建立成功,则直接扔给worker线程处理;若建立失败,则扔给boss线程处理(因为是非阻塞的,
可能一开始会建立不成功)。
(2)worker线程,负责处理建立成功的连接
8. SSL
(1)客户端, SSLHandler放在位置1, 触发握手开始的操作放到最后一个Handler的channelConnected中,
客户端握手过程(handshake):
1. beginHandshake, 执行代理任务(就是ssl会话过程中的一些计算);
2. 输出数据到服务端wrapNonAppData(这时没应用数据);
3. 检查握手状态;
最新技术文章: