https://blog.csdn.net/kc58236582/article/details/51506896
里面提到了开发者定位来调整缓冲区的逻辑,进而理了一下。
frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/AbstractLogdSizePreferenceController.java
关键prop是persist.logd.size,平常我们可以在debug的时候设置这个prop,比如1000000(大约1MB),然后再重启logd,start logd_reinit.或者修改init.rc来在debug开关打开的时候来设置。
console:/ # getprop | grep logd
[init.svc.logd]: [running]
[init.svc.logd-reinit]: [stopped]
[logd.logpersistd]: []
[logd.logpersistd.enable]: [true]
[persist.logd.logpersistd]: []
[persist.logd.size]: [1048576]
[ro.boottime.logd]: [14823168131]
[ro.boottime.logd-reinit]: [15467994381]
[ro.logd.size.stats]: [64K]
console:/ # start logd-reinit
console:/ # [153290.668414@0] logd.daemon: reinit
下面是逻辑
这个类实现了OnPreferenceChangeListener接口,需要实现onPreferenceChange方法。这个方法会在每次变更Preference Screen时都会调用到。
public abstract class AbstractLogdSizePreferenceController extends
DeveloperOptionsPreferenceController implements Preference.OnPreferenceChangeListener
比如
public void setTitle(CharSequence title) {
if (title == null && mTitle != null || title != null && !title.equals(mTitle)) {
mTitleRes = 0;
mTitle = title;
notifyChanged();
}
}
notifiyChanged就会调用回调
/**
* Should be called when the data of this {@link Preference} has changed.
*/
protected void notifyChanged() {
if (mListener != null) {
mListener.onPreferenceChange(this);
}
}
这样在选择某个新的缓冲区的值之后,比如1M
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference == mLogdSize) {
writeLogdSizeOption(newValue);
return true;
} else {
return false;
}
}
public void writeLogdSizeOption(Object newValue) {
boolean disable = (newValue != null) &&
(newValue.toString().equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE));
String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
if (currentTag == null) {
currentTag = "";
}
// filter clean and unstack all references to our setting
String newTag = currentTag.replaceAll(
",+" + SELECT_LOGD_TAG_SILENCE, "").replaceFirst(
"^" + SELECT_LOGD_TAG_SILENCE + ",*", "").replaceAll(
",+", ",").replaceFirst(
",+$", "");
if (disable) {
newValue = SELECT_LOGD_MINIMUM_SIZE_VALUE;
// Make sure snet_event_log get through first, but do not override
String snetValue = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
if ((snetValue == null) || (snetValue.length() == 0)) {
snetValue = SystemProperties.get(SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY);
if ((snetValue == null) || (snetValue.length() == 0)) {
SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, DEFAULT_SNET_TAG);
}
}
// Silence all log sources, security logs notwithstanding
if (newTag.length() != 0) {
newTag = "," + newTag;
}
// Stack settings, stack to help preserve original value
newTag = SELECT_LOGD_TAG_SILENCE + newTag;
}
if (!newTag.equals(currentTag)) {
SystemProperties.set(SELECT_LOGD_TAG_PROPERTY, newTag);
}
String defaultValue = defaultLogdSizeValue();
final String size = ((newValue != null) && (newValue.toString().length() != 0)) ?
newValue.toString() : defaultValue;
SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, defaultValue.equals(size) ? "" : size);
SystemProperties.set("ctl.start", "logd-reinit");
SystemPropPoker.getInstance().poke();
updateLogdSizeValues();
}
SELECT_LOGD_SIZE_PROPERTY即是persist.logd.size, 写ctl.start为logd-reinit是要启动logd-reinit service,即重启logd。后面的日志删除就会根据这个prop来进行配置。缓冲区大了就会少丢日志。
public static class PokerTask extends AsyncTask<Void, Void, Void> {
@VisibleForTesting
String[] listServices() {
return ServiceManager.listServices();
}
@VisibleForTesting
IBinder checkService(String service) {
return ServiceManager.checkService(service);
}
@Override
protected Void doInBackground(Void... params) {
String[] services = listServices();
if (services == null) {
Log.e(TAG, "There are no services, how odd");
return null;
}
for (String service : services) {
IBinder obj = checkService(service);
if (obj != null) {
Parcel data = Parcel.obtain();
try {
obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
} catch (RemoteException e) {
// Ignore
} catch (Exception e) {
Log.i(TAG, "Someone wrote a bad service '" + service
+ "' that doesn't like to be poked", e);
}
data.recycle();
}
}
return null;
}
}