EventBus实现Activity与Service通信

现在有如下需要:在一个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 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(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中获取,如果在缓存中没有找到图片,则从网络上获取,并将获取的图片放入缓存中。

你可能感兴趣的:(EventBus实现Activity与Service通信)