上一篇文章分析了ClusterMananger的整体结构和核心算法 细读百度地图点聚合源码(上),此文是接着上一篇来的。
在本文中,我们将学习如何在UI线程中做大量的操作,并且不会造成界面卡顿。
上次我们讲到ClusterManager类中的cluster()方法,调用ClusterTask后台线程处理核心算法,既然有doInBackground()后台任务函数,就会有onPostExecute()函数来处理后台线程返回的结果,这一篇我们就分析怎么处理返回的结果。
那么我们就从返回的结果开始吧!
private class ClusterTask extends AsyncTask<Float, Void, Set<? extends Cluster<T>>> { @Override protected Set<? extends Cluster<T>> doInBackground(Float... zoom) { mAlgorithmLock.readLock().lock(); try { return mAlgorithm.getClusters(zoom[0]); } finally { mAlgorithmLock.readLock().unlock(); } } @Override protected void onPostExecute(Set<? extends Cluster<T>> clusters) { mRenderer.onClustersChanged(clusters); } }
上面就是ClusterTask的源码,后台任务处理算法,然后返回数据给主线程,返回的就是一个Set<? extends Cluster<T>>类型的对象,就是一个包含若干个cluster对象的集合,而cluster对象又是一个包含若干MyItem(implements ClusterItem)的集合。
并且,每个cluster中的那些MyItem都是确定可以聚合成一个点的。
那到底要怎么处理这个cluster集合呢?
我们看到是mRenderer来处理的,就是源码中DefaultClusterRenderer类,当然我们也可以继承这个类来实现我们自己的Renderer类,这个等有需求再细说吧。
我们还是先来分析DefaultClusterRenderer这个类究竟做了些什么处理。
一切都是从onClustersChanged(clusters)这个方法开始(该方法从ClusterRenderer接口实现而来)。这个方法很简单,里面只有一句代码,所以我们还得往里面跟踪。@Override public void onClustersChanged(Set<? extends Cluster<T>> clusters) { mViewModifier.queue(clusters); }
至此我们会有两个疑问:mViewModifier是什么东东?queue()函数又是做什么用的呢?
ViewModifier其实是一个继承于Handler的类,内部只有两个函数:handleMessage()和queue()
我们先来看queue()函数:
public void queue(Set<? extends Cluster<T>> clusters) { synchronized (this) { // Overwrite any pending cluster tasks - we don't care about intermediate states. mNextClusters = new RenderTask(clusters); } sendEmptyMessage(RUN_TASK); }
在函数内部创建一个RenderTask对象,这是一个Runnable接口的实现类,也就是一个未启动的线程。
然后发送一条Message给handleMessage函数。大家应该可以猜到,在handleMessage中肯定会启动这