我正在尝试制作一个包含一个片段的卡,该片段具有多个textView,这些片段将显示CPU核心的频率。我面临的问题是,我不能在不影响整个Activity性能的情况下更新TextViews。我尝试使用处理程序的postdelayed来调用更新视图所需的函数,但它也冻结了该特定时间间隔的整个UI。 这是我的活动代码和两个片段。
父母片段
package com.psychokernelupdater.frags;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.psychokernelupdater.R;
public class TunerMain extends Fragment {
public TunerMain() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tuner_main, container, false);
Fragment cpu = new CPUFreq();
getChildFragmentManager().beginTransaction()
.add(R.id.cpuFreqFrag, cpu)
.commitAllowingStateLoss();
return view;
}
}
儿童片段
package com.psychokernelupdater.frags;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.psychokernelupdater.R;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.Scanner;
public class CPUFreq extends Fragment {
static float[] freq = new float[8];
TextView[] C = new TextView[8];
float[] fre;
String[] curFreq = new String[8];
String units, f;
String[] cpuData;
Handler handler = new Handler();
int delay = 500;
public CPUFreq() {
}
public static float[] getCPUFrequencyCurrent() {
for (int i = 0; i < 8; i++) {
try {
freq[i] = readSystemFileAsInt("/sys/devices/system/cpu/cpu" + String.valueOf(i) + "/cpufreq/scaling_cur_freq");
} catch (Exception e) {
freq[i] = -1;
}
}
return freq;
}
private static int readSystemFileAsInt(final String pSystemFile) throws Exception {
InputStream in = null;
try {
final Process process = new ProcessBuilder(new String[]{"/system/bin/cat", pSystemFile}).start();
in = process.getInputStream();
final String content = readFully(in);
return Integer.parseInt(content);
} catch (final Exception e) {
throw new Exception(e);
}
}
public static final String readFully(final InputStream pInputStream) {
final StringBuilder sb = new StringBuilder();
final Scanner sc = new Scanner(pInputStream);
while (sc.hasNextLine()) {
sb.append(sc.nextLine());
}
return sb.toString();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.cpu_freq, container, false);
C[0] = (TextView) view.findViewById(R.id.CPU0);
C[1] = (TextView) view.findViewById(R.id.CPU1);
C[2] = (TextView) view.findViewById(R.id.CPU2);
C[3] = (TextView) view.findViewById(R.id.CPU3);
C[4] = (TextView) view.findViewById(R.id.CPU4);
C[5] = (TextView) view.findViewById(R.id.CPU5);
C[6] = (TextView) view.findViewById(R.id.CPU6);
C[7] = (TextView) view.findViewById(R.id.CPU7);
handler.postDelayed(new Runnable() {
@Override
public void run() {
cpuData = updateFreq();
updViews(C, cpuData);
handler.postDelayed(this, delay);
}
}, delay);
return view;
}
public String[] updateFreq() {
fre = getCPUFrequencyCurrent();
for (int i = 0; i < 8; i++) {
if (fre[i] == -1) {
curFreq[i] = " OFFLINE";
} else {
if (fre[i] < 1000000) {
DecimalFormat df = new DecimalFormat("###");
f = df.format(fre[i] / 1000);
units = " MHz";
} else {
DecimalFormat df = new DecimalFormat("###.#");
f = df.format(fre[i] / 1000000);
units = " GHz";
}
curFreq[i] = f + units;
}
}
return curFreq;
}
public void updViews(TextView[] Arr, String[] cpu) {
for (int i = 0; i < 8; i++) {
Arr[i].setText(Html.fromHtml("<b>" + "CPU " + Integer.toString(i + 1) + " : " + "</b>" + cpu[i]));
}
}
@Override
public void onPause() {
super.onPause();
}
}
请告诉我如何在不冻结整个UI的情况下完成此更新。
答案 0 :(得分:1)
默认情况下,处理程序是在同一线程上创建的。您需要使用处理程序创建一个新线程,如下所示:
HandlerThread thread = new HandlerThread("background");
Handler handler;
现在您可以在onCreateView
中启动代码,如下所示:
thread.start();
handler = new Handler(thread.getLooper())
handler.postDelayed(new Runnable() {
@Override
public void run() {
cpuData = updateFreq();
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
updViews(C, cpuData);
}
});
handler.postDelayed(this, delay);
}
}, delay);
请注意,视图是在runOnUiThread
中更新的,否则,您将遇到异常,因为视图只能在UI线程中更新。
也不要忘记在onDestroyView
中停止线程:
@Override
public void onDestroyView() {
super.onDestroyView();
thread.quitSafely();
}