Java 如何并行连续递增多个RecyclerView值
上下文 使用Java 如何并行连续递增多个RecyclerView值,java,android,multithreading,android-recyclerview,Java,Android,Multithreading,Android Recyclerview,上下文 使用RecyclerView项,每个项都有标签和值textview,还有一个开始按钮 目标 在按下开始按钮时开始并继续递增值 必须能够通过按钮单独启动每个项目的值 一旦启动,多个值必须能够并行连续递增 问题 用户界面(值TextView,单击按钮等)在两个或更多值开始递增后变慢。不确定如何处理线程(尝试了HandlerThread/runOnUiThread,当前为每个MyValue对象使用单个线程),请参阅下面code中的MyValue.start() 在更新RecyclerVie
RecyclerView
项,每个项都有标签和值textview
,还有一个开始按钮
目标
- 在按下开始<代码>按钮时开始并继续递增值
- 必须能够通过按钮单独启动每个项目的值
- 一旦启动,多个值必须能够并行连续递增
问题 用户界面(值
TextView
,单击按钮
等)在两个或更多值开始递增后变慢。不确定如何处理线程(尝试了HandlerThread
/runOnUiThread
,当前为每个MyValue
对象使用单个线程),请参阅下面code中的MyValue.start()
在更新RecyclerView
时,如何在不降低UI速度的情况下并行地不断增加单个值
到目前为止已经尝试了什么
- 使用
HandlerThread
和runOnUiThread
- 为每个
MyValue
对象使用单个线程
- 考虑到
AsyncTask
,但在将来,“递增多值”行为可能需要在后台运行,而不依赖于活动
(即,只有当活动
在前台时才更新GUI),因此该行为可能会移动到边界服务
- 可以使用
LiveData
让RecyclerView
项目根据MyValue
中的值进行观察和更新,但是,不确定LiveData如何使用MyValue
和ValuesAdapter
代码
主要活动
public class MainActivity extends AppCompatActivity {
ArrayList<MyValue> mValues;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
mValues = new ArrayList<>();
mValues.add(new MyValue("value 1"));
mValues.add(new MyValue("value 2"));
mValues.add(new MyValue("value 3"));
ValuesAdapter valuesAdapter = new ValuesAdapter(mValues);
recyclerView.setAdapter(valuesAdapter);
}
}
问题
似乎是通过MyValue.ValueListener.onTick()
完成了高频率的工作(即在递增值和更新RecyclerView
TextView
值时跳过大约2000帧)
解决方案
当前的解决方案是延迟onTick
以仅每1秒触发一次,即用以下内容替换MyValue.start()
:
private Runnable mRepeatIncrementRunnable = new Runnable() {
@Override
public void run() {
if (mShouldIncrement) {
increment();
if (mListener != null) {
mListener.onTick(mCurrentValue);
}
} else {
mHandler.removeCallbacks(this);
return;
}
mHandler.postDelayed(this, mTickIntervalMs);
}
};
public void start() {
mShouldIncrement = true;
mHandler.post(mRepeatIncrementRunnable);
}
public class ValueController {
private List<MyValue> mValues;
public ValueController(List<MyValue> values) {
mValues = values;
}
public void incrementActiveValues() {
for (int i = 0; i < mValues.size(); i++) {
MyValue value = mValues.get(i);
if (value.getShouldIncrement()) {
value.increment();
}
}
}
}
public class MyValue {
private String mLabel;
private int mCurrentValue;
private boolean mShouldIncrement;
private Handler mHandler;
private ValueListener mListener;
public MyValue(String label) {
mLabel = label;
HandlerThread handlerThread = new HandlerThread("HandlerThread1");
handlerThread.start();
mHandler = new Handler(handlerThread.getLooper());
}
public String getLabel() {
return mLabel;
}
public int getValue() {
return mCurrentValue;
}
public void increment() {
mCurrentValue++;
}
public void start() {
mShouldIncrement = true;
new Thread(new Runnable() {
@Override
public void run() {
while (mShouldIncrement) {
increment();
if (mListener != null) {
mListener.onTick(mCurrentValue);
}
}
}
}).start();
// mHandler.post(new Runnable() {
// @Override
// public void run() {
// while (mShouldIncrement) {
// increment();
// if (mListener != null) {
// mListener.onTick(mCurrentValue);
// }
// }
// }
// });
}
public void setListener(ValueListener listener) {
mListener = listener;
}
public interface ValueListener {
void onTick(int currentValue);
}
public boolean getShouldIncrement() {
return mShouldIncrement;
}
}
private Runnable mRepeatIncrementRunnable = new Runnable() {
@Override
public void run() {
if (mShouldIncrement) {
increment();
if (mListener != null) {
mListener.onTick(mCurrentValue);
}
} else {
mHandler.removeCallbacks(this);
return;
}
mHandler.postDelayed(this, mTickIntervalMs);
}
};
public void start() {
mShouldIncrement = true;
mHandler.post(mRepeatIncrementRunnable);
}