如何解决此内存泄漏(IntentService,Runnable,ObjectBox,存储库)?

时间:2019-02-03 05:45:27

标签: java android performance memory-leaks objectbox

我有一个IntentService,其中我正在重复一个Runnable 每秒

我正在Runnable内向MyItemsRepository请求记录,该记录使用的是 ObjectBox

某处存在内存泄漏 Android Profiler 显示大量消耗的“本机” 。方法getAllByDate()被分配了很多。

这似乎是泄漏,但我不知道如何解决。

有什么主意吗? 提前非常感谢!

应用

public class App extends Application {
    @Nullable
    private BoxStore boxStore;

    private static App instance;

    public static App getApp() {
        return instance;
    }

    public BoxStore getBoxStore() {
        if (boxStore == null) {
            boxStore = MyObjectBox.builder().androidContext(App.this).build();
        }
        return boxStore;
    }

     @Override
    public void onCreate() {
        super.onCreate();

        Intent service = new Intent(this, MyService.class);
        this.startService(service);
    }
}

我的服务

public class MyService extends IntentService {

    private final static String TAG = "MyService";

    @Nullable
    private Runnable runnable;

    @Nullable
    private List<Item> myItems;

    public MyService() {
        super(TAG);

        myItems = new ArrayList<>();
    }

    @Override
    public void onDestroy () {
        super.onDestroy();  
        myItems = null; // trying to get rid off the allocation?
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {        
        HandlerThread handlerThread = new HandlerThread(TAG + "_handlerThread");
        handlerThread.start();

        Handler handler  = new Handler(handlerThread.getLooper());
        runnable = () -> {
            try {
                processMyItems();
                if (runnable != null) {
                    handler.postDelayed(runnable, 1000); // restart
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
                if (runnable != null) {
                    handler.postDelayed(runnable, 1000); // retry
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        handler.postDelayed(runnable, 1000); // first run
    }

    protected void processMyItems() throws InterruptedException, Exception {
        myItems = MyItemsRepository.getInstance().getAllByDate();

        // ... do stuff with myItems ...        
    }
}

MyItemsRepository

public class MyItemsRepository {

    private final static String TAG = "MyItemsRepository";

    private static MyItemsRepository instance;

    @Nullable
    private Box<MyItem> box;

    /**
     * Singleton
     * @return old or new instance
     */
    public static MyItemsRepository getInstance() {
        if (MyItemsRepository.instance == null) {
            Logger.d(TAG, "new instance");
            MyItemsRepository.instance = new MyItemsRepository();            
        }

        return MyItemsRepository.instance;
    }

    public List<MyItems> getAllByDate() {
        if (box == null) {
            return new ArrayList<>();
        }

        ElapsedTimer et = new ElapsedTimer();

        List<MyItem> items = box.query()
                .order(MyItem_.createdAt, QueryBuilder.DESCENDING)
                .build()
                .find();

        Logger.d(TAG, "getAllByDate() " + et.getElapsedMillisAsString());
        return items;
    }
}

ElapsedTimer (助手)

public class ElapsedTimer {
    private long startTime;

    public ElapsedTimer() {
        startTime = System.currentTimeMillis();
    }

    public String getElapsedMillisAsString() {
        return String.format("Elapsed: %s ms", getElapsedMillis());
    }
}

0 个答案:

没有答案