EventBusはActivityとServiceの通信を実現

8755 ワード

サービスでタイミングスレッドを起動し、ネットワークから一定時間おきに画像を取得し、取得した画像をActivity UIに更新する必要があります.
(1)bindService()メソッドでサービスを開始すると,サービスとActivityの通信は可能であるが,ローカルサービスをバインドすることは煩雑である.(2)startService()メソッドでサービスを開始すると、通常、Activityはサービスと通信できません.BroadcastReceiverのグループを借りることができますが、BroadcastReceiverはIntentを通じてわずかなデータしか伝達できず、大きな画像は伝達できません.(3)上記の問題を解決するために,EventBusにより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);
    }
}

サービスクラス

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);
        }
    }
}

サービスではLruCacheを使用してネットワークから取得したピクチャをキャッシュし、タイマがBitmapオブジェクトを取得するたびにLruCacheから取得し、キャッシュにピクチャが見つからない場合はネットワークから取得し、取得したピクチャをキャッシュに入れる.