积累

作者: ttyttytty | 来源:发表于2021-05-21 16:29 被阅读0次

class reference {
private final String TAG = reference.class.getSimpleName();// 日志TAG

private final AuthenticationProvider authenticationProvider = null; // 成员待初始化,内部不变final,非必须
private final HealthKitService healthKitService; // 对象做成员
private HandlerThread mBTStatusHandlerThread = null; // 线程对象
private DeviceStatusHandler mStatusHandler = null; // handler对象

private static final Object lock = new Object(); // 对象锁

@BindView(R.id.ll_verifycode)
protected LinearLayout mLlVerifyCode;// 注意修饰符

// 界面类的第一个函数
@Override
public int getLayoutId() {
    return R.layout.activity_main;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AppUtils.setStatusTranslucent(this);
    init(); // 初始化成员 层次分离
    initView(); // 初始化界面
    checkPermission(); // 其他逻辑
}

// 初始化成员
private void init() {
    if (null == bridgeManager) {
        projectCode = Constants.STUDY_ID;
        bridgeManager = BridgeManager2.getInstance(projectCode);
        authenticationProvider = bridgeManager.getAuthenticationProvider();
    }
}

// 初始化界面
private void initView() {
}

// 单例写法instance

// 注意判空,哪怕是自定义的成员变量

// 线程
private void initRunThread() {
    if (null != mBTStatusHandlerThread) {
        mBTStatusHandlerThread = null;
    }
    // 实例化命令发送线程句柄
    mBTStatusHandlerThread = new HandlerThread(TAG);
    // 启动线程
    mBTStatusHandlerThread.start();
    // 实例化命令发送Handler
    mStatusHandler = new DeviceStatusHandler(mBTStatusHandlerThread.getLooper());
}

// handler
private class DeviceStatusHandler extends Handler {
    public DeviceStatusHandler(Looper looper) {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
        case DEVICE_STATUS_MSG:
            checkDeviceStatus();
            break;
        }
    }
}

//handler发送消息
mSendHandler.sendEmptyMessage(SYNC_HEALTH_SPORT_DATA);
mHandler.post/postDelayed(new Runnable())   
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
                                    @Override
                                    public void run() {
                                        RxBus.get().post(Constants.UPLOAD_SUCCESS_TASK, 0);
                                    }
                                }, 1000);
RxBus.get().post(Constants.SYNC_DEVICE, syncBTDataStatus);RxBus.toObservable();

// 对象锁
private   byte [] lock  =   new   byte [ 0 ];   //  定一个instance变量
 synchronized (lock) {
    if (localDevices.contains(deviceInfo)) {
        localDevices.remove(deviceInfo);
    }
    localDevices.add(deviceInfo);}

 
Lock lock = new XxxLock();   
 // ...    boolean isLocked = lock.tryLock();   
 if (isLocked) {        
 try {            
 doBiz();       
 } 
 finally {  
 lock.unlock();        
 }    


@Override
public toString(){ 
}

@Override
public int hashCode() {
    return userId.hashCode();
}

@Override
public boolean equals(@Nullable Object obj) {
    if (null == obj || !(obj instanceof ActivityData))
        return false;
    ActivityData other = (ActivityData) obj;
    return Objects.equals(userId, other.getUserId()) && Objects.equals(dayStartTime, other.getDayStartTime());
}

}

线程:
MyThread extends Thread
@override run()
}
new MyThread ().start();

new Thread(() -> addRawSleepDataToDB(returnObject)).start();

MyRunnable implemnts Runnable{
@Override run()
}
new Thread(new MyRunnable()).start();


new Handler.post(new Runnable());  //lamadabc表达式

RxBus.get().post(Constants.DEVICE_CONNECT_TYPE, deviceInfo);

序列化Gson:
Type type = new TypeToken<List<SensorProDeviceInfo>>() {
}.getType();
if (!TextUtils.isEmpty(data)) {
List<SensorProDeviceInfo> deviceInfoList = new Gson().fromJson(data, type);
Object<->String,Gson,参考GsonUtils,to/fromJson (如: public String toString() {return GsonUtils.toString(this);})
gson = new GsonBuilder()
// 不过滤空值
.serializeNulls()
// 设置字段命名转换规则
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
// 设置字段序列化/反序列化过滤规则
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.STATIC)
// 自定义类型解析器,提高Gson容错性
.registerTypeHierarchyAdapter(List.class, listDeserial)
.create();

系统资源,通过context/PackageManager,获取项目的资源(包名,meta-signature,sha256,string.xml,assets,SharedPreferences): 本质上是流
String packageName = context.getPackageName();
String isCheckJoinResearch = context.getString(R.string.isCheckJoinResearch); 写在string.xml中
SharedPreferences sharedPreferences = applicationContext.getSharedPreferences(PREFERENCES_FILE + "_" + projectCode, Context.MODE_PRIVATE);
(ConnectivityManager) Utils.getApp().getSystemService(Context.CONNECTIVITY_SERVICE)).
BluetoothManager bluetoothManager = (BluetoothManager) Utils.getApp().getSystemService(Context.BLUETOOTH_SERVICE);
LocationManager locationManager = (LocationManager) Utils.getApp().getSystemService(Context.LOCATION_SERVICE);
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
获取apk包信息:getPackageInfo
获取App的运行模式:BUILDConfig等配置:build.gradle: buildTypes
获取自定义的属性attrs.xml文件。TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularPointBarView); mTypedArray.recycle();在xml中定属性的值
从不同位置获取Bitmap
//判断是否授权
private boolean checkPermissionGranted(String permission) {
return ContextCompat.checkSelfPermission(SensorApplication.getContext(), permission)
== PackageManager.PERMISSION_GRANTED;
}
context.getSharedPreferences(name, Context.MODE_PRIVATE);

参考sensorpro-AuthValidUtils
获取路径file.getName();
检查文件是否为空,判断长度即可 path-》 if (file.length() > 0) {
/**
* 新建文件路径
*
* @return
*/
public static String createFilePath() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.ENGLISH);
String timeStr = dateFormat.format(new Date());
String File_PATH = Environment.getExternalStorageDirectory() + "/sleepbigdata/sensordata/" + timeStr;
File filePath = new File(File_PATH);
if (!filePath.exists()) {
boolean pathMkdir = filePath.mkdirs();
if (!pathMkdir) {
return null;
}
}
return File_PATH;
}

连续配置: public ECGCommandGenerator setScene(String scene){
this.mScene = scene;
return this;
}

广播:
//注册监听系统时间发生变化广播
IntentFilter filterTimeChanged = new IntentFilter(Intent.ACTION_TIME_CHANGED);
mContext.registerReceiver(mTimeChangedReceiver, filterTimeChanged);
//发送广播
//接收广播

Rxjava:
1.sdk-RxSchedulersHelper:
public static <T> ObservableTransformer<T, T> io_io() {
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io());
}
};
}
public <T> Observable<T> toObservable(final int code, final Class<T> eventType) {
return mBus.ofType(Message.class)
.filter(new Predicate<Message>() {
@Override
public boolean test(Message message) throws Exception {
//过滤code和eventType都相同的事件
return message.getCode() == code && eventType.isInstance(message.getObject());
}
})
.map(new Function<Message, Object>() {
@Override
public Object apply(Message message) throws Exception {
return message.getObject();
}
}).cast(eventType);
}
2.合并observable:UserInfoUpload: obsArgs = Observable.merge(uploadAvatarObs, uploadUserInfoObs);//合并多个observable
Observable<BannerResp> observableBanner = articleProviderTmp.getBannerList2();
Observable<ArticleInfoResp> observableArticle = articleProviderTmp.getArticleList(pageInfo);
Observable<Object> merge = Observable.merge(observableBanner, observableArticle);
final ArticleInfos[] banner = {new ArticleInfos()};
final ArticleInfos[] articleList = {new ArticleInfos()};
Observable.merge(observableBanner, observableArticle)
.subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(Object articleInfoResp) {
                    if (articleInfoResp instanceof BannerResp) {
                        banner[0] = ((BannerResp) articleInfoResp).getData();
                    } else if (articleInfoResp instanceof ArticleInfoResp) {
                        articleList[0] = ((ArticleInfoResp) articleInfoResp).getData();
                    }
                }

                @Override
                public void onError(Throwable e) {
                    mView.onLoadDiscoveriesFailed();
                }

                @Override
                public void onComplete() {
                    mView.onDiscoveriesPrepared(banner[0], articleList[0]);
                    Log.d(TAG, "loadData:getDiscoveryData onComplete: ");
                }
            });
}
3.//将所有正在处理的Subscription都添加到CompositeSubscription中。统一退出的时候注销观察
    private CompositeDisposable mCompositeDisposable;
    
    
    //在界面退出等需要解绑观察者的情况下调用此方法统一解绑,防止Rx造成的内存泄漏
    public void dispose() {
        if (mCompositeDisposable != null && !mCompositeDisposable.isDisposed()) {
            mCompositeDisposable.dispose();
        }
        }
4.Android SDK中  DefaultTransformer、NewThreadTransformer与compose :    对流进行变换操作
5.多个流事件一个接一个:包装成Observable,使用Observable流(flatmap)
    多个observable封装flatmap,错误返回值与成功后要做的事的返回值是一样的。(如何确定每件事的返回值?根据是否需要传数据,后面的逻辑需要什么。)
    将回调转为observable?为什么不能是完成后Observable.just出去?,   如何确定每件事的返回值?根据是否需要传数据 ?是否需要 MessageDataResponse<Data>
    return Observable.create(new ObservableOnSubscribe<MessageResponse>() {方法  emitter出去} 
    public Observable<MessageDataResponse<Map<Long, List<SingleSportData>>>> getSingleSportDatas(long startTime, long endTime) 
    API返回observable
    Observable.just()     万事皆可Observable.just,

flatmap流,多个接口流,return 第一个调返回Observabvle的接口,或者是自己Observable.just(万事)出来一个Observable.然后往下走flatmap   (e.g.   loginhelper.login()/getSportHealthDatas())
       多个返回Observabvle的相同的接口/函数,for循环flatmap出obsStart=obsStart.flatmap()。注意,定义一个index,因为异步与调用主逻辑不在一个线程(e.g.getSingleSportData())
        sportHealthData数据需要拼接,数据异步获取,每次flatmap成功保存中间数据,activityMaps[0] = resp.getData();sleepMaps[0] = resp.getData();最后mergeData(activityMaps[0], sleepMaps[0])
        flatmap不是一上来就判断getsuccess(我们把上一步接口的返回值都包成Observable<MessageResponse>了,所以判断),需要根据业务(上传时,flatmap起始的Observable.just(activityData)就是判断if (null == activityDataList))

        observable.flatMap(new Function<ResponseModel, ObservableSource<ResponseModel>>() {
                    @Override
                    public ObservableSource<ResponseModel> apply(ResponseModel responseModel) throws Exception {
  • 6.生产一个observable
    Observable.create(new ObservableOnSubscribe<List<SportSumData>>() {
    @Override
    public void subscribe(ObservableEmitter<List<SportSumData>> emitter) throws Exception {

              emitter.onNext(sportUploadList);
              emitter.onComplete();
          }
      });
    

    7.流有多个或者不确定是否上传,可以考虑将流都构造出来:Observable。create();或者本身就是Observable返回值的,统一使用concat/merge等操作符上传。
    上传是异步的,使用AtomicInteger或计数串行上传。 AtomicInteger count = new AtomicInteger(0);

lamada表达式里需要更新的值,需要在外部定义成final

数据库:
预编译:// String sql = "delete from ? where ? = '?'";
// Connection connection = DriverManager.getConnection();
// PreparedStatement ps = connection.prepareStatement(sql);
// try {
// ps.setString(1, "tb_userinfo");
// ps.setString(2, "projectCode");
// ps.setString(3, projectCode);
// } catch (SQLException e) {
// e.printStackTrace();
// }
连着两步操作数据库,需要事务( database.beginTransaction();try{do some db operations database.setTransactionSuccessful(); }finally{database.setTransactionSuccessful();})

注解:
Hiresearch的注解的使用:
1.定义注解类、、(元注解的修饰,啥时候起作用,只针对哪些成员起作用,要继承不)
2.注解的处理逻辑定义(
3.注解继承,是否有效,,,需要添加@inherited注解,且父类的抽象方法不能被继承
//获取元数据名称及元数据版本号
@HiResearchMetadata
public HiResearchMetadataInfo getHiResearchMetadataInfo(Class<? extends HiResearchBaseMetadata> hClass) {
//如果没有HiResearchMetadata 注解,则取类名作为元数据名,默认版本号为"1"
HiResearchMetadataInfo hiResearchMetadataInfo = new HiResearchMetadataInfo(hClass.getSimpleName(), "1");
Annotation[] classAnnotations = hClass.getAnnotations();
if (null != classAnnotations) {
for (Annotation annotation : classAnnotations) {
if (annotation instanceof HiResearchMetadata) {
// 从注解中获取元数据名称及版本号
HiResearchMetadata hiResearchMetadata = (HiResearchMetadata) annotation;
hiResearchMetadataInfo.setName(hiResearchMetadata.name());
hiResearchMetadataInfo.setVersion(hiResearchMetadata.version());
break;
}
}
}
return hiResearchMetadataInfo;
})

@interface HiResearchField
(  //从注解获取
    Annotation[] annotations = field.getAnnotations();
    if (null != annotations) {
        for (Annotation annotation : annotations) {
            if (annotation instanceof HiResearchField) {
                HiResearchField hiResearchField = (HiResearchField) annotation;
                if (!Strings.isNullOrEmpty(hiResearchField.name())) {
                    hiReseaerchMetadataSerializeField.setSerializeFieldName(hiResearchField.name());
                }
                break;
            }
            if (annotation instanceof HiResearchAttachmentField) {
                HiResearchAttachmentField hiResearchField = (HiResearchAttachmentField) annotation;
                if (!Strings.isNullOrEmpty(hiResearchField.name())) {
                    hiReseaerchMetadataSerializeField.setSerializeFieldName(hiResearchField.name());
                }
                hiReseaerchMetadataSerializeField.setFieldType(HiResearchDataType.ATTACHMENT);
                break;
            }
        }
    }
    return hiReseaerchMetadataSerializeField;)
    @HiResearchDataType
    上面
    @HiResearchAttachmentField:

枚举:SensorProUnitePPGConfigure ,最好@IntDef
@IntDef/@StringDef本身是个Android中提供的一种注解,用于替代枚举的使用。
使用:
添加依赖:compile 'com.android.support:support-annotations:22.0.0'
@IntDef({STRING,TEXT,BIGINT,BOOLEAN,DOUBLE,ATTACHMENT,
ARRAY,
HEARTRATE,RRI,
BLOODPRESSURE,BLOODSUGAR,
SLEEPSTATISTICS,
CALORIESBURNED,DISTANCE,STEPCOUNT,
BODYHEIGHT,BODYWEIGHT})
@Retention(RetentionPolicy.SOURCE)
public @interface HiResearchDataType { //通过枚举,限制其他值不能传入,但是为什么要定义HiResearchDataType注解类?在哪里解析?限制变量作用,无实际逻辑,知识做值。https://www.kancloud.cn/zhangzihao/articles/325612
public static final int STRING = 0x00000001;
public static final int TEXT = 0x00000002;
public static final int BIGINT = 0x00000003;
public static final int BOOLEAN = 0x00000004;
public static final int DOUBLE = 0x00000005;
public static final int ATTACHMENT = 0x00000006;

    public static final int ARRAY = 0x00000010;

    public static final int HEARTRATE = 0x00000021;
    public static final int RRI = 0x00000022;

    public static final int BLOODPRESSURE = 0x00000031;
    public static final int BLOODSUGAR = 0x00000032;

    public static final int SLEEPSTATISTICS = 0x00000041;

    public static final int CALORIESBURNED = 0x00000051;
    public static final int DISTANCE = 0x00000052;
    public static final int STEPCOUNT = 0x00000053;

    public static final int BODYHEIGHT = 0x00000061;
    public static final int BODYWEIGHT = 0x00000062;
}       

泛型:
void onResponse(int err_code, T objData);数据T转为需要的类型,例如List?
泛型参考:SharedPreferencesJsonDAO,注意提前声明类型<T>,记得通配符super和extends,
分类别处理逻辑时,instanceof分支(UserInfoDao)
<? extends T > 所有的泛型类必须<=类T,父类上限是T,?是T的子类。 不能往里存(子类的内容/粒度大于父类,不知道存哪里啊),只能往外取
<? super T> 所有的泛型类必须>=类T,子类的下限是T,?是T的父类。 存正常(基类的粒度/内容都小于T,都可以存下),取必须赋给OBject(不知道父类super向上究竟的界在哪里,只能取最大父类Object)
PECS:producer extends consumer super:频繁存/set要有最大粒度的底盘兜住,所以用super;频繁取/get,用extends,可以取出来放到指定盘子里。
类型转换原则:(内容少的->内容多的,粒度小的->粒度大的,内存小空间->大空间),少的部分赋默认值/方法。
int->double,可以,知识其他的内存填默认值0;
double->int,不可以,内容/精度丢失。
基类=子类(基类指向子类,基类小内容内存覆盖子类多内容,缺失的部分赋默认值,调用子类的默认构造函数);
子类=父类(子类大内存扣在父类小内存上,丢失)。
https://blog.csdn.net/sjm19901003/article/details/44743801

编码:
hexUtil&& Integer.parseInt(tlvs.get(l).getTag(), 16)
Base64.decode(输入String 二进制后,每6位分割,查找Base64的64个字符映射为另一个串)
String digest = BaseEncoding.base64().encode(messageDigest.digest());
加密:
encrypt(String key密钥, String ivParameter偏移向量, String data)
Java.Cipher加密器= EncryptUtil.initAESCipher(publicKey, ivParameter);
EncryptHelper(jkstore加密)&&EncryptUtil(SHA。AES加密)

蓝牙:
获取Mac(根据系统版本,不同方式获取Mac地址:getLocalMacAddressFromWifiInfo、getLocalInetAddress、根据IP地址获取MAC地址、android 7.0及以上扫描各个网络接口获取mac地址getMachineHardwareAddress、根据busybox获取本地Mac)

日期工具类:
common包 DateUtil/TimeUtils, Calender(获取日月天,丰富API) && Date && timeStamp
String.format(context.getString(R.string.format_total_time), hour, minute, second);

华为账号登录:(HMSAgent)
Hms登录需要的activity有没有在manifest中配置
HMSAgent:init()初始化在Mainapplication 中,Login时连接connect(),内部类Hwid.signIn()登录HMS

restful api:
为了适配不同终端平台(Web,iOS和Android),使用同一套接口访问资源。
URL::authservice/v1/auth/hwAccountSignIn
public <T> T getClient(Class<T> service) {
List<Converter.Factory> factories = new ArrayList<>();
factories.add(GsonConverterFactory.create(GsonUtils.GSON));
//OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (证书可信) {
}
builder.connectTimeout().addInterceptor();//配置
builder.addInterceptor(interceptors);
OkHttpClient okHttpClient = builder.build();
//Retrofit
Retrofit.Builder builderRetrofit = new Retrofit.Builder();
设置URL和client(OkHttpClient)
Retrofit retrofit = builderRetrofit.addConverterFactory(factories)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
retrofit.create(service);
}
interceptor:
在OkHttp内部是使用拦截器来完成请求和响应,利用的是责任链设计模式,可以用来转换,重试,重写请求的机制。
覆写 @Override
public Response intercept(Chain chain) throws IOException实现想做的功能(压缩。日志等,例:ErrorResponseInterceptor)
factorires.add(GsonConverterFactory.create(GsonUtils.GSON));处理请求(Observable<Respone>),不然要覆写那四个函数,代码量少,可扩展(coede处理情况,修改的话,就直接修改factory)
实际请求执行:RealCall.execute(创建RealCall,各个interceptors,责任链执行,返回response: Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest);return chain.proceed(originalRequest);)

tips:
从SDK获取工具类
多个参数个数略有差异的函数,在最全的里面都定义好,其他的填充默认值(null等等看业务需要),构造函数
错误码值需要考虑分类,如服务端就5XX。
Convertor 参考bridge的Convertor:convert bean to map
UserAccountDao extends SharedPreferencesJsonDAO sharedpreferences的一个实现,考虑了不同signin信息的泛型类 ,instanceof Long
参数非空:@NonNull修饰,Optional
三目运算符的使用,if就想到
callback里面可以放置变量
多个参数,有的时候传入,有的时候不传入,需要构造一个通用的全参功能函数,其他传入默认值,在全参代码里需要判断。(多参构造函数)
不要在外面判断功能分支,在内部(setView(“无数据”);setView(“有数据”);-》setView(null);setView(data){if(null=data){}……})
页面与逻辑分离,页面的异步(通过控件进行异步等待,如登录控件。注意控件间的enalbe控制)
多个控件的监听,可以不单独写,类implements View.OnClickListener,直接.setOnClickListener(this);公用一个onClick{内部分id,实现逻辑} ,参考updateDialog
多用注解,清晰
异步:
RXjava,在结果里处理后续操作(页面,数据库……提前做成一个interface())
回调定义一个结束接口callback.onFinish(),后续在onFinish()里处理:例如,同步设备侧数据,写完数据库后调callback.onfinish,在onfinish里读取数据库
异步优势考虑使用标志位,结束就置位,其他地方一直检查,,, MonitorService.getInstance().updateStatus(getTaskType(), TaskStatus.START);
多样类似的事,考虑抽成抽象类,例如获取设备侧的不同数据,定一个abstract class syncHelper,syn抽象函数,greendao的session,读取泛型数据库函数,,,继承出多个如HRSyncHelper/SleepSyncHelper,实现具体行为
通用流程也可以考虑做成行为接口(public class RealTimeAccServiceImpl extends UploadDataService<List<AccData>> implements RealTimeService<List<AccData>> {),不一定都是抽象类
子类不喜欢,override父方法, @Override 重写,可实现多态
for里面不要新建变量/try-catch,性能差
一个类中常用的多个字段(计数,标志位),可以考虑抽取一个类
每个模块自己的错误码加前缀
画图注意有来有回,参考HMS或者网络通信图
日结表

相关文章

  • 积累积累再积累

    能不能过成自己想要的样子, 全在于自己的自主选择 积累积累再积累 耐心耐心再耐心 仅此而已,别无他法~

  • 积累积累~~~

    正式起稿开始了~这样每天画一点可能三个月册子就完整喽~~~ balabala 以前总觉得时间过得好慢~活得时间太漫...

  • 1000个简单好用的朋友圈文案模板044

    文/夏小沫 一、前言 人生是一个默默积累的过程,积累知识,积累经验,积累成长,积累好皮肤,积累好身材,积累健康,积...

  • 积累

    时代进入一个终生学习的阶段,在这个阶段里,我们一生都在学习,每天都在阅读、听课、总结、复盘。主动的、被动的,都要不...

  • 积累

    1-人都是被自己的情绪打败的,尤其是自己的情绪,不要因为别人的一句话就失眠。 2-早起练车,晕到现在,年纪大了果然...

  • 积累

    突然意识到积累的重要性。 每天坚持做一件事情,那么这件事情可能就会帮助你完成更好的事情,你有没有每天都会做的很好的...

  • 积累

    突然想到,小学初中语文都会有一项作业,抄写日积月累的古诗词名言警句什么的。哈哈,现在模型改的还是很顺利的嘛。很开心...

  • 积累

    我是展鹏教育的大邢老师,这是我加入日记星球的第76篇原创日记。 不知不觉已经是第76篇,偶尔也能写出阅读量超400...

  • 积累

    任何经历,都是一种积累。 人生有很多苦难,是躲不掉的,所以需要忍耐; 人生有很多闲气,是避不开的,所以需要忍耐。 ...

  • 积累

    2018年5月26日 星期六 天气:晴 今天晚上我如约来到东城街道新型市民 学校安宁社区父母学堂智慧家长...

网友评论

      本文标题:积累

      本文链接:https://www.haomeiwen.com/subject/tuiwjltx.html