<commit_before>package com.ilis.memoryoptimizer.activity;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.ilis.memoryoptimizer.R;
import com.ilis.memoryoptimizer.adapter.ProcessListAdapter;
import com.ilis.memoryoptimizer.modle.ProcessInfo;
import com.ilis.memoryoptimizer.util.ProcessInfoDiff;
import com.ilis.memoryoptimizer.util.ProcessInfoProvider;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.processCount)
    TextView processCount;
    @BindView(R.id.memoryStatus)
    TextView memoryStatus;
    @BindView(R.id.processList)
    RecyclerView processList;
    @BindView(R.id.refreshLayout)
    SwipeRefreshLayout refreshLayout;

    private List<ProcessInfo> processInfo = new ArrayList<>();
    private ProcessListAdapter adapter;
    private Disposable disposable;
    private LinearLayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initViews();
        setListener();
    }

    @Override
    protected void onResume() {
        super.onResume();
        refreshLayout.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        refreshLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        refreshLayout.setRefreshing(true);
                        ProcessInfoProvider.update();
                    }
                });
    }

    @Override
    protected void onDestroy() {
        unBindProcessList();
        super.onDestroy();
    }

    private void initViews() {
        refreshLayout.setColorSchemeResources(R.color.colorAccent);
        layoutManager = new LinearLayoutManager(this);
        processList.setLayoutManager(layoutManager);
        processList.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.left = (int) getResources().getDimension(R.dimen.item_offset);
                outRect.right = (int) getResources().getDimension(R.dimen.item_offset);
                outRect.bottom = (int) getResources().getDimension(R.dimen.item_offset);
            }
        });
        adapter = new ProcessListAdapter(this, processInfo);
        processList.setAdapter(adapter);
    }


    private void setListener() {
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                ProcessInfoProvider.update();
            }
        });
        bindProcessList();
    }

    @OnClick({
            R.id.checkAll,
            R.id.checkOthers,
            R.id.killAll,
    })
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.checkAll:
                int size = processInfo.size();
                for (int i = 0; i < size; i++) {
                    ProcessInfo info = processInfo.get(i);
                    if (!info.isChecked()) {
                        info.setChecked(true);
                        adapter.notifyItemChanged(i);
                    }
                }
                break;
            case R.id.checkOthers:
                for (ProcessInfo info : processInfo) {
                    info.setChecked(!info.isChecked());
                }
                adapter.notifyDataSetChanged();
                break;
            case R.id.killAll:
                if (refreshLayout.isRefreshing()) {
                    return;
                }
                refreshLayout.setRefreshing(true);
                ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                for (ProcessInfo info : processInfo) {
                    if (info.getPackName().equals(getPackageName())) {
                        continue;
                    }
                    if (info.isChecked()) {
                        am.killBackgroundProcesses(info.getPackName());
                    }
                }
                ProcessInfoProvider.update();
                break;
        }
    }

    private void bindProcessList() {
        if (disposable == null || disposable.isDisposed()) {
            disposable = ProcessInfoProvider.getProvider()
                    .observeOn(Schedulers.computation())
                    .doOnNext(new Consumer<List<ProcessInfo>>() {
                        @Override
                        public void accept(List<ProcessInfo> newInfo) throws Exception {
                            for (ProcessInfo info : processInfo) {
                                if (info.isChecked()) {
                                    for (ProcessInfo newOne : newInfo) {
                                        if (info.getPackName().equals(newOne.getPackName())) {
                                            newOne.setChecked(info.isChecked());
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    })
                    .map(new Function<List<ProcessInfo>, DiffUtil.DiffResult>() {
                        @Override
                        public DiffUtil.DiffResult apply(List<ProcessInfo> newInfo) throws Exception {
                            DiffUtil.DiffResult diffResult =
                                    DiffUtil.calculateDiff(new ProcessInfoDiff(newInfo, processInfo));
                            processInfo.clear();
                            processInfo.addAll(newInfo);
                            return diffResult;
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DiffUtil.DiffResult>() {
                        @Override
                        public void accept(DiffUtil.DiffResult diffResult) throws Exception {
                            refreshLayout.setRefreshing(false);
                            diffResult.dispatchUpdatesTo(adapter);
                            processCount.setText(
                                    String.format(
                                            getString(R.string.process_count),
                                            ProcessInfoProvider.getProcessCount()
                                    ));
                            memoryStatus.setText(
                                    String.format(
                                            getString(R.string.memory_status),
                                            ProcessInfoProvider.getSystemMemStatus()
                                    ));<commit_msg>fix crash<commit_after>package com.ilis.memoryoptimizer.activity;

import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import com.ilis.memoryoptimizer.R;
import com.ilis.memoryoptimizer.adapter.ProcessListAdapter;
import com.ilis.memoryoptimizer.modle.ProcessInfo;
import com.ilis.memoryoptimizer.util.ProcessInfoDiff;
import com.ilis.memoryoptimizer.util.ProcessInfoProvider;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.processCount)
    TextView processCount;
    @BindView(R.id.memoryStatus)
    TextView memoryStatus;
    @BindView(R.id.processList)
    RecyclerView processList;
    @BindView(R.id.refreshLayout)
    SwipeRefreshLayout refreshLayout;

    private List<ProcessInfo> processInfo = new ArrayList<>();
    private ProcessListAdapter adapter;
    private Disposable disposable;
    private LinearLayoutManager layoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        initViews();
        setListener();
    }

    @Override
    protected void onResume() {
        super.onResume();
        refreshLayout.getViewTreeObserver()
                .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        refreshLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        refreshLayout.setRefreshing(true);
                        ProcessInfoProvider.update();
                    }
                });
    }

    @Override
    protected void onDestroy() {
        unBindProcessList();
        super.onDestroy();
    }

    private void initViews() {
        refreshLayout.setColorSchemeResources(R.color.colorAccent);
        layoutManager = new LinearLayoutManager(this);
        processList.setLayoutManager(layoutManager);
        processList.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.left = (int) getResources().getDimension(R.dimen.item_offset);
                outRect.right = (int) getResources().getDimension(R.dimen.item_offset);
                outRect.bottom = (int) getResources().getDimension(R.dimen.item_offset);
            }
        });
        adapter = new ProcessListAdapter(this, processInfo);
        processList.setAdapter(adapter);
    }


    private void setListener() {
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                ProcessInfoProvider.update();
            }
        });
        bindProcessList();
    }

    @OnClick({
            R.id.checkAll,
            R.id.checkOthers,
            R.id.killAll,
    })
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.checkAll:
                int size = processInfo.size();
                for (int i = 0; i < size; i++) {
                    ProcessInfo info = processInfo.get(i);
                    if (!info.isChecked()) {
                        info.setChecked(true);
                        adapter.notifyItemChanged(i);
                    }
                }
                break;
            case R.id.checkOthers:
                for (ProcessInfo info : processInfo) {
                    info.setChecked(!info.isChecked());
                }
                adapter.notifyDataSetChanged();
                break;
            case R.id.killAll:
                if (refreshLayout.isRefreshing()) {
                    return;
                }
                refreshLayout.setRefreshing(true);
                ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                for (ProcessInfo info : processInfo) {
                    if (info.getPackName().equals(getPackageName())) {
                        continue;
                    }
                    if (info.isChecked()) {
                        am.killBackgroundProcesses(info.getPackName());
                    }
                }
                ProcessInfoProvider.update();
                break;
        }
    }

    private void bindProcessList() {
        if (disposable == null || disposable.isDisposed()) {
            disposable = ProcessInfoProvider.getProvider()
                    .observeOn(Schedulers.computation())
                    .doOnNext(new Consumer<List<ProcessInfo>>() {
                        @Override
                        public void accept(List<ProcessInfo> newInfo) throws Exception {
                            for (ProcessInfo info : processInfo) {
                                if (info.isChecked()) {
                                    for (ProcessInfo newOne : newInfo) {
                                        if (info.getPackName().equals(newOne.getPackName())) {
                                            newOne.setChecked(info.isChecked());
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    })
                    .map(new Function<List<ProcessInfo>, DiffUtil.DiffResult>() {
                        @Override
                        public DiffUtil.DiffResult apply(List<ProcessInfo> newInfo) throws Exception {
                            DiffUtil.DiffResult diffResult =
                                    DiffUtil.calculateDiff(new ProcessInfoDiff(newInfo, processInfo));
                            processList.setLayoutFrozen(true);
                            processInfo.clear();
                            processInfo.addAll(newInfo);
                            return diffResult;
                        }
                    })
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<DiffUtil.DiffResult>() {
                        @Override
                        public void accept(DiffUtil.DiffResult diffResult) throws Exception {
                            refreshLayout.setRefreshing(false);
                            processList.setLayoutFrozen(false);
                            diffResult.dispatchUpdatesTo(adapter);
                            processCount.setText(
                                    String.format(
                                            getString(R.string.process_count),
                                            ProcessInfoProvider.getProcessCount()
                                    ));
                            memoryStatus.setText(
                                    String.format(
                                            getString(R.string.memory_status),
                                            ProcessInfoProvider.getSystemMemStatus()
                                    ));
{'fraction_non_alphanumeric': 0.0834238262535931, 'fraction_numerical': 0.0007665282657297988, 'mean_word_length': 1.5276073619631902, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 46, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4670901', 'n_tokens_mistral': 3724, 'n_tokens_neox': 3523, 'n_words': 597}