当前位置: 编程技术>移动开发
本页文章导读:
▪Handler+ExecutorService(线程池)+MessageQueue形式+缓存模式 Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式
android线程池的理解,预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存 下面看他们的理解。Handler+Run.........
▪ 怎么找到一个数组中第三大数字并输出它所在的位置 如何找到一个数组中第三大数字并输出它所在的位置
面试题:如何找到一个数组中第三大数字并输出它所在的位置延伸问题:如何找到一个数组中第N大元素并输出它所在的位置
public class Fi.........
▪ 输出出一个数组中出现次数最多的数目字以及它出现的次数 输出出一个数组中出现次数最多的数字以及它出现的次数
查找一个数组中出现次数最多的数字以及它出现的次数并输出出来
public class FindMostAppearTime {
public static void getMostAppearNumber(int [] .........
[1]Handler+ExecutorService(线程池)+MessageQueue形式+缓存模式
来源: 互联网 发布时间: 2014-02-18
Handler+ExecutorService(线程池)+MessageQueue模式+缓存模式
android线程池的理解,预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存 下面看他们的理解。
Handler+Runnable模式
我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable模式。
这里为何不是新开线程的原因请参看这篇文章:Android Runnable 运行在那个线程 这里的代码其实是在UI 主线程中下载图片的,而不是新开线程。
我们运行下面代码时,会发现他其实是阻塞了整个界面的显示,需要所有图片都加载完成后,才能显示界面。
Handler+Thread+Message模式
这种模式使用了线程,所以可以看到异步加载的效果。
核心代码:
这时候我们可以看到实现了异步加载, 界面打开时,五个ImageView都是没有图的,然后在各自线程下载完后才把图自动更新上去。
Handler+ExecutorService(线程池)+MessageQueue模式
能开线程的个数毕竟是有限的,我们总不能开很多线程,对于手机更是如此。
这个例子是使用线程池。Android拥有与Java相同的ExecutorService实现,我们就来用它。
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
线程池的信息可以参看这篇文章:Java&Android的线程池-ExecutorService 下面的演示例子是创建一个可重用固定线程数的线程池。
核心代码
这里我们象第一步一样使用了 handler.post(new Runnable() { 更新前段显示当然是在UI主线程,我们还有 executorService.submit(new Runnable() { 来确保下载是在线程池的线程中。
Handler+ExecutorService(线程池)+MessageQueue+缓存模式
下面比起前一个做了几个改造:
封装的类:
说明:
final参数是指当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。参看:Java关键字final、static使用总结
这里使用SoftReference 是为了解决内存不足的错误(OutOfMemoryError)的,更详细的可以参看:内存优化的两个类:SoftReference 和 WeakReference
前段调用:
android线程池的理解,预习了一下android异步加载的例子,也学习到了一个很重要的东东 那就是线程池+缓存 下面看他们的理解。
Handler+Runnable模式
我们先看一个并不是异步线程加载的例子,使用 Handler+Runnable模式。
这里为何不是新开线程的原因请参看这篇文章:Android Runnable 运行在那个线程 这里的代码其实是在UI 主线程中下载图片的,而不是新开线程。
我们运行下面代码时,会发现他其实是阻塞了整个界面的显示,需要所有图片都加载完成后,才能显示界面。
import java.io.IOException; import java.net.URL; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.util.Log; import android.widget.ImageView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); loadImage("http://www.baidu.com/img/baidu_logo.gif", R.id.imageView1); loadImage(<img id="\"aimg_zGDMA\"" onclick="\"zoom(this," this.src,="" 0,="" 0)\"="" zoom\"" file="\"http://www.chinatelecom.com.cn/images/logo_new.gif\"" onmouseover="\"img_onmouseoverfunc(this)\"" lazyloadthumb="\"1\"" border="\"0\"" alt="\"\"">", R.id.imageView2); loadImage("http://cache.soso.com/30d/img/web/logo.gif, R.id.imageView3); loadImage("http://csdnimg.cn/www/images/csdnindex_logo.gif", R.id.imageView4); loadImage("http://images.cnblogs.com/logo_small.gif", R.id.imageView5); } private Handler handler = new Handler(); private void loadImage(final String url, final int id) { handler.post(new Runnable() { public void run() { Drawable drawable = null; try { drawable = Drawable.createFromStream( new URL(/blog_article/url/index.html).openStream(), "image.gif"); } catch (IOException e) { Log.d("test", e.getMessage()); } if (drawable == null) { Log.d("test", "null drawable"); } else { Log.d("test", "not null drawable"); } // 为了测试缓存而模拟的网络延时 SystemClock.sleep(2000); ((ImageView) MainActivity.this.findViewById(id)) .setImageDrawable(drawable); } }); } }
Handler+Thread+Message模式
这种模式使用了线程,所以可以看到异步加载的效果。
核心代码:
import java.io.IOException; import java.net.URL; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.util.Log; import android.widget.ImageView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); loadImage2("http://www.baidu.com/img/baidu_logo.gif", R.id.imageView1); loadImage2("http://www.chinatelecom.com.cn/images/logo_new.gif", R.id.imageView2); loadImage2("http://cache.soso.com/30d/img/web/logo.gif", R.id.imageView3); loadImage2("http://csdnimg.cn/www/images/csdnindex_logo.gif", R.id.imageView4); loadImage2("http://images.cnblogs.com/logo_small.gif", R.id.imageView5); } final Handler handler2 = new Handler() { @Override public void handleMessage(Message msg) { ((ImageView) MainActivity.this.findViewById(msg.arg1)) .setImageDrawable((Drawable) msg.obj); } }; // 采用handler+Thread模式实现多线程异步加载 private void loadImage2(final String url, final int id) { Thread thread = new Thread() { @Override public void run() { Drawable drawable = null; try { drawable = Drawable.createFromStream( new URL(/blog_article/url/index.html).openStream(), "image.png"); } catch (IOException e) { Log.d("test", e.getMessage()); } // 模拟网络延时 SystemClock.sleep(2000); Message message = handler2.obtainMessage(); message.arg1 = id; message.obj = drawable; handler2.sendMessage(message); } }; thread.start(); thread = null; } }
这时候我们可以看到实现了异步加载, 界面打开时,五个ImageView都是没有图的,然后在各自线程下载完后才把图自动更新上去。
Handler+ExecutorService(线程池)+MessageQueue模式
能开线程的个数毕竟是有限的,我们总不能开很多线程,对于手机更是如此。
这个例子是使用线程池。Android拥有与Java相同的ExecutorService实现,我们就来用它。
线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理。当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程对象所带来的性能开销,节省了系统的资源。
线程池的信息可以参看这篇文章:Java&Android的线程池-ExecutorService 下面的演示例子是创建一个可重用固定线程数的线程池。
核心代码
import java.io.IOException; import java.net.URL; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.util.Log; import android.widget.ImageView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); loadImage3("http://www.baidu.com/img/baidu_logo.gif", R.id.imageView1); loadImage3("http://www.chinatelecom.com.cn/images/logo_new.gif", R.id.imageView2); loadImage3("http://cache.soso.com/30d/img/web/logo.gif", R.id.imageView3); loadImage3("http://csdnimg.cn/www/images/csdnindex_logo.gif", R.id.imageView4); loadImage3("http://images.cnblogs.com/logo_small.gif", R.id.imageView5); } private Handler handler = new Handler(); private ExecutorService executorService = Executors.newFixedThreadPool(5); // 引入线程池来管理多线程 private void loadImage3(final String url, final int id) { executorService.submit(new Runnable() { public void run() { try { final Drawable drawable = Drawable.createFromStream( new URL(/blog_article/url/index.html).openStream(), "image.png"); // 模拟网络延时 SystemClock.sleep(2000); handler.post(new Runnable() { public void run() { ((ImageView) MainActivity.this.findViewById(id)) .setImageDrawable(drawable); } }); } catch (Exception e) { throw new RuntimeException(e); } } }); } }
这里我们象第一步一样使用了 handler.post(new Runnable() { 更新前段显示当然是在UI主线程,我们还有 executorService.submit(new Runnable() { 来确保下载是在线程池的线程中。
Handler+ExecutorService(线程池)+MessageQueue+缓存模式
下面比起前一个做了几个改造:
- 把整个代码封装在一个类中
- 为了避免出现同时多次下载同一幅图的问题,使用了本地缓存
封装的类:
import java.lang.ref.SoftReference; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.SystemClock; public class AsyncImageLoader3 { // 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动) public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>(); private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务 private final Handler handler = new Handler(); /** * * @param imageUrl * 图像url地址 * @param callback * 回调接口 * <a href="/index.html"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"" target="\"_blank\"">@return</a> 返回内存中缓存的图像,第一次加载返回null */ public Drawable loadDrawable(final String imageUrl, final ImageCallback callback) { // 如果缓存过就从缓存中取出数据 if (imageCache.containsKey(imageUrl)) { SoftReference<Drawable> softReference = imageCache.get(imageUrl); if (softReference.get() != null) { return softReference.get(); } } // 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中 executorService.submit(new Runnable() { public void run() { try { final Drawable drawable = loadImageFromUrl(/blog_article/imageUrl/index.html); imageCache.put(imageUrl, new SoftReference<Drawable>( drawable)); handler.post(new Runnable() { public void run() { callback.imageLoaded(drawable); } }); } catch (Exception e) { throw new RuntimeException(e); } } }); return null; } // 从网络上取数据方法 protected Drawable loadImageFromUrl(/blog_article/String imageUrl/index.html) { try { // 测试时,模拟网络延时,实际时这行代码不能有 SystemClock.sleep(2000); return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png"); } catch (Exception e) { throw new RuntimeException(e); } } // 对外界开放的回调接口 public interface ImageCallback { // 注意 此方法是用来设置目标对象的图像资源 public void imageLoaded(Drawable imageDrawable); } }
说明:
final参数是指当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。参看:Java关键字final、static使用总结
这里使用SoftReference 是为了解决内存不足的错误(OutOfMemoryError)的,更详细的可以参看:内存优化的两个类:SoftReference 和 WeakReference
前段调用:
import android.app.Activity; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.widget.ImageView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); loadImage4("http://www.baidu.com/img/baidu_logo.gif", R.id.imageView1); loadImage4("http://www.chinatelecom.com.cn/images/logo_new.gif", R.id.imageView2); loadImage4("http://cache.soso.com/30d/img/web/logo.gif", R.id.imageView3); loadImage4("http://csdnimg.cn/www/images/csdnindex_logo.gif", R.id.imageView4); loadImage4("http://images.cnblogs.com/logo_small.gif", R.id.imageView5); } private AsyncImageLoader3 asyncImageLoader3 = new AsyncImageLoader3(); // 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程 private void loadImage4(final String url, final int id) { // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行 Drawable cacheImage = asyncImageLoader3.loadDrawable(url, new AsyncImageLoader3.ImageCallback() { // 请参见实现:如果第一次加载url时下面方法会执行 public void imageLoaded(Drawable imageDrawable) { ((ImageView) findViewById(id)) .setImageDrawable(imageDrawable); } }); if (cacheImage != null) { ((ImageView) findViewById(id)).setImageDrawable(cacheImage); } } }
[2] 怎么找到一个数组中第三大数字并输出它所在的位置
来源: 互联网 发布时间: 2014-02-18
如何找到一个数组中第三大数字并输出它所在的位置
面试题:如何找到一个数组中第三大数字并输出它所在的位置
延伸问题:如何找到一个数组中第N大元素并输出它所在的位置
面试题:如何找到一个数组中第三大数字并输出它所在的位置
延伸问题:如何找到一个数组中第N大元素并输出它所在的位置
public class FindThirdLarge { public static void getThirdLargeNumber(int [] array,int nLarge){ int count = 0;//大于某个数字的个数 int location = 0;//参考值的索引 int referenceValue = 0;//参考值 boolean flag = true;//循环执行标志 while(flag){ referenceValue = array[location]; for(int i=0;i<array.length;i++){ if( (i!=location) && (array[i]>referenceValue) ){ count +=1; } } if(count == (nLarge-1)){ flag = false; System.out.println("第"+nLarge+"大数字是:"+referenceValue+";位置在:"+location); }else{ count = 0; location+=1; flag = true; } } } public static void main(String[] args) { int ar [] = {3,6,4,9,5,2,8}; getThirdLargeNumber(ar,3); } }
[3] 输出出一个数组中出现次数最多的数目字以及它出现的次数
来源: 互联网 发布时间: 2014-02-18
输出出一个数组中出现次数最多的数字以及它出现的次数
查找一个数组中出现次数最多的数字以及它出现的次数并输出出来
查找一个数组中出现次数最多的数字以及它出现的次数并输出出来
public class FindMostAppearTime { public static void getMostAppearNumber(int [] array){ HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); int time = 0; Map.Entry<Integer,Integer> maxEntry = null; for(int i=0;i<array.length;i++){ if(map.get(array[i]) == null){ map.put(array[i],1); }else{ map.put(array[i],1+(Integer)map.get(array[i])); } } for(Map.Entry<Integer,Integer> entry:map.entrySet()){ if(entry.getValue()>time){ time = entry.getValue(); maxEntry = entry; } } System.out.println("数组中出现次数最多的数字是="+maxEntry.getKey()+";出现的次数是:"+maxEntry.getValue()); } public static void main(String[] args) { int ar [] = {3,6,2,4,9,5,2,8,8,8,8,2}; getMostAppearNumber(ar); } }
最新技术文章: