现在有如下需要:在一个Service启动一个定时线程,每隔一段时间从网络上获取一张图片,并将获取的图片更新到ActivityUI上。
(1)如果通过bindService()方法启动一个Service,虽然可以实现Service和Activity通信,但是绑定本地Service比较繁琐。
(2)如果通过startService()方法启动一个Service,通常情况下,Activity无法与Service通信。虽然可以借助BroadcastReceiver的帮组,但是BroadcastReceiver通过Intent只能传递少量的数据,无法传递较大的图片。
(3)为了解决上面的问题,可以通过EventBus来实现Service传递图片给Activity。具体代码如下:
MainActivity类
public class MainActivity extends Activity
{
private ImageView imageView;
private Button show;
Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
EventBus.getDefault().register(this);
intent = new Intent(this , ChangeService.class);
imageView = (ImageView) findViewById(R.id.picture);
show = (Button) findViewById(R.id.show);
show.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
startService(intent);
}
});
}
public void onEventMainThread(Bitmap bitmap)
{
if (bitmap != null)
imageView.setImageBitmap(bitmap);
}
@Override
protected void onDestroy()
{
super.onDestroy();
stopService(intent);
EventBus.getDefault().unregister(this);
}
}
Service类
public class ChangeService extends Service
{
private int imgId = 1;
private LruCache<Integer , Bitmap> lruCache;
private Bitmap showingImg;
@Override
public void onCreate()
{
super.onCreate();
initCache();
}
@Override
public int onStartCommand(final Intent intent, int flags, final int startId)
{
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
if (imgId > 4)
imgId = 1;
if (getBitmapFromCache(imgId) != null)
{
showingImg = getBitmapFromCache(imgId);
}
else
{
showingImg = getBitmapFromUrl(imgId);
if (showingImg != null)
{
putBitmapToCache(imgId , showingImg);
}
}
EventBus.getDefault().post(showingImg);
imgId++;
}
} , 0 , 3000);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy()
{
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent)
{
return null;
}
private void initCache()
{
int maxMemory = (int) Runtime.getRuntime().maxMemory();
int cacheSize = maxMemory / 10;
lruCache = new LruCache<Integer, Bitmap>(cacheSize)
{
@Override
protected int sizeOf(Integer key, Bitmap value)
{
return value.getByteCount();
}
};
}
private Bitmap getBitmapFromUrl(Integer imgId)
{
InputStream is = null;
Bitmap bitmap;
try
{
URL url = new URL("http://192.168.1.100/pic" + imgId +".jpg");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(conn.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
conn.disconnect();
return bitmap;
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return null;
}
private Bitmap getBitmapFromCache(Integer imgId)
{
return lruCache.get(imgId);
}
private void putBitmapToCache(Integer imgId , Bitmap bitmap)
{
if (getBitmapFromCache(imgId) == null)
{
lruCache.put(imgId, bitmap);
}
}
}
Service中使用了一个LruCache来缓存从网路上获取的图片,定时器每次需要获取Bitmap对象时,先从LruCache中获取,如果在缓存中没有找到图片,则从网络上获取,并将获取的图片放入缓存中。