Android 開(kāi)發(fā)藝術(shù)探索筆記之五 -- 理解 RemoteViews

學(xué)習(xí)內(nèi)容:

  • RemoteViews 在通知欄和桌面小部件上的應(yīng)用
  • RemoteViews 的內(nèi)部機(jī)制
  • RemoteViews 的意義

RemoteView 的應(yīng)用

實(shí)際開(kāi)發(fā)中,RemoteViews 主要用在通知欄和桌面小部件的開(kāi)發(fā)過(guò)程中。通知欄主要通過(guò) NotificationManager 的 notify 方法實(shí)現(xiàn)璃谨,桌面小部件則是通過(guò) AppWidgetProvider 來(lái)實(shí)現(xiàn),其本質(zhì)也是一個(gè)廣播。

通知欄和桌面小部件更新界面時(shí),RemoteView 無(wú)法像 View 一樣在 Activity 中直接更新猾编,因?yàn)榻缑孢\(yùn)行在系統(tǒng)的 SystemServer 進(jìn)程,需要跨進(jìn)程更新升敲。

下面簡(jiǎn)單介紹 RemoteView 的應(yīng)用

  1. RemoteView 在通知欄上的應(yīng)用(主要為 自定義布局

    (適配 Android 8.0)

    //創(chuàng)建NotificationManager實(shí)例
    NotificationManager mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    
    //創(chuàng)建NotificationChannel實(shí)例
    //參數(shù)說(shuō)明:
    //id:NotificationChannel的唯一標(biāo)識(shí)
    //name:NotificationChannel的名稱(chēng)答倡,在Settings可看到
    //importance:對(duì)channel設(shè)置重要性,更改見(jiàn)后續(xù)表格
    NotificationChannel mChannel = new NotificationChannel("id","name",NotificationManager.IMPORTANCE_DEFAULT);
    mManager.createNotificationChannel(mChannel);
    
    //創(chuàng)建PendingIntent
    Intent intent = new Intent(this,SecondActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
    
    //創(chuàng)建RemoteView
    RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.layout_notification);
    remoteViews.setTextViewText(R.id.msg,"xx");
    remoteViews.setImageViewResource(R.id.icon,R.drawable.icon);
    remoteViews.setOnclidePendingIntent(R.id.clickable,pendingIntent);
    
    //創(chuàng)建builder,并設(shè)置一系列屬性
    Notification.Builder builder = new Notification.Builder(this,"id");
    builder.setSmallIcon(R.drawable.ic_launcher_background)
            .setContentTitle("title")
            .setContentText("text")
            //以上三個(gè)為必需的屬性
            .setAutoCancel(true);
    
    //Android 7.0 之后需要通過(guò)Notification.Builder設(shè)置contentView
    builder.setCustomContentView(remoteViews).
        
    //創(chuàng)建通知
    Notification notification = builder.build();
    //推送通知
    mManager.notify(1,notification);
    

    ? RemoteViews 和 View 不同驴党,每個(gè)方法中幾乎都要求傳入一個(gè) id 參數(shù)瘪撇,比如 setTextViewText(int viewId, CharSequence text),需要傳入TextView 的 id。

    ? 直觀原因 是因?yàn)?RemoteViews 沒(méi)有提供和 View 類(lèi)似的 findViewById 這個(gè)方法倔既,因此我們無(wú)法獲取到 RemoteView 中的子 View恕曲。(實(shí)際原因并非如此,后面詳細(xì)介紹)

  2. RemoteViews 在桌面小部件上的應(yīng)用

    利用 AppWidgetProvider渤涌,本質(zhì)是廣播佩谣。

    1. 定義小部件界面

      在 res/layout/ 新建一個(gè) xml 文件,命名為 widget.xml实蓬,名稱(chēng)和內(nèi)容可自定義茸俭,視小部件具體需求而定。

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">
      
          <ImageView
              android:id="@+id/imageView1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:src="@drawable/icon" />
      </LinearLayout>
      
    2. 定義小部件配置信息

      在 res/xml/ 下新建 appwidget_provider_info.xml安皱,名稱(chēng)任意调鬓。

      <?xml version="1.0" encoding="utf-8"?>
      <appwidget-provider    xmlns:android="http://schemas.android.com/apk/res/android"
       
              //使用的初始化布局
            android:initialLayout="@layout/widget"
            //小工具的最小尺寸
            android:minHeight="84dp"
            android:minWidth="84dp"
            //自動(dòng)更新周期,毫秒單位
            android:updatePeriodMillis="864000"/>
      
      
    3. 定義小部件的實(shí)現(xiàn)類(lèi)

      繼承 AppWidgetProvider酌伊,功能為簡(jiǎn)單的 點(diǎn)擊后隨機(jī)切換圖片袖迎。

      public class MyAppWidgetProvider extends AppWidgetProvider {
          public static final String TAG = "ImgAppWidgetProvider";
          public static final String CLICK_ACTION = "cn.hudp.androiddevartnote.action.click";
          private static int index;
      
          @Override
          public void onReceive(Context context, Intent intent) {
              super.onReceive(context, intent);
              if (intent.getAction().equals(CLICK_ACTION)) {
                  RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
                  AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
      
                  updateView(context, remoteViews, appWidgetManager);
              }
          }
      
          @Override
          public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
              super.onUpdate(context, appWidgetManager, appWidgetIds);
              RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
      
              updateView(context, remoteViews, appWidgetManager);
          }
      
          // 隨機(jī)更新圖片
          public void updateView(Context context, RemoteViews remoteViews, AppWidgetManager appWidgetManager) {
              index = (int) (Math.random() * 3);
              if (index == 1) {
                  remoteViews.setImageViewResource(R.id.iv, R.mipmap.haimei1);
              } else if (index == 2) {
                  remoteViews.setImageViewResource(R.id.iv, R.mipmap.haimei2);
              } else {
                  remoteViews.setImageViewResource(R.id.iv, R.mipmap.haimei3);
              }
              Intent clickIntent = new Intent();
              clickIntent.setAction(CLICK_ACTION);
              PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, clickIntent, 0);
              remoteViews.setOnClickPendingIntent(R.id.iv, pendingIntent);
              appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidgetProvider.class), remoteViews);
          }
      }
      
    4. 在 AndroidManifest.xml 中聲明小部件

      原因:本質(zhì)是廣播組件,因此需要注冊(cè)

      <receiver android:name=".MyAppWidgetProvider">
          <meta-data
              android:name="android.appwidget.provider"
              android:resource="@xml/appwidget_provider_info">
              </meta-data>
          <intent-filter>
            //識(shí)別小部件的單擊行為
              <action android:name="com.whdalive.action.click" />
               //作為小部件的標(biāo)識(shí)腺晾,必須存在
              <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
          </intent-filter>
      </receiver>
      
    5. 廣播分發(fā)

      當(dāng)廣播到來(lái)之后,AppWidgetProvider 會(huì)自動(dòng)根據(jù)廣播的 Action 通過(guò) onReceive 來(lái)自動(dòng)分發(fā)廣播辜贵,相關(guān)方法如下

      1. onEnable: 當(dāng)該窗口小部件第一次添加到桌面時(shí)調(diào)用的方法悯蝉,可添加多次但只在第一次調(diào)用。
      2. onUpdate: 小部件被添加時(shí)或者每次小部件更新時(shí)都會(huì)調(diào)用一次該方法托慨,小部件的更新時(shí)機(jī)是有updatePeriodMillis來(lái)指定鼻由,每個(gè)周期小部件就會(huì)自動(dòng)更新一次。
      3. onDeleted: 每刪除一次桌面小部件就調(diào)用一次厚棵。
      4. onDisabled: 當(dāng)最后一個(gè)該類(lèi)型的小部件被刪除時(shí)調(diào)用該方法蕉世。
      5. onRestored:當(dāng)接收到 ACTION_APPWIDGET_RESTORED 廣播,從備份恢復(fù)小部件時(shí)調(diào)用
      6. onAppWidgetOptionsChanged:當(dāng)接收到 ACTION_APPWIDGET_OPTIONS_CHANGED 廣播婆硬,小部件的尺寸位置發(fā)生變化時(shí)調(diào)用狠轻。
      7. onReceive: 這是廣播的內(nèi)置方法,用于分發(fā)具體事件給其他方法彬犯。
  3. PendingIntent 概述

    1. 基本介紹

      1. PendingIntent 表示一種處于 Pending(待定向楼、等待、即將發(fā)生)狀態(tài)的意圖谐区;
      2. 典型應(yīng)用場(chǎng)景是給 RemoteViews 添加點(diǎn)擊事件湖蜕,(RemoteViews 運(yùn)行在遠(yuǎn)程進(jìn)程)
      3. 通過(guò) send 和 cancel 方法來(lái)發(fā)送和取消特定的待定 Intent。
    2. 分類(lèi)

      1. 啟動(dòng) Activity -> getActivity(Context context, int requestCode, Intent intent, int flags)

      2. 啟動(dòng) Service -> getService(Context context, int requestCode, Intent intent, int flags)

      3. 發(fā)送廣播 -> getBroadcast(Context context, int requestCode, Intent intent, int flags)

     參數(shù)說(shuō)明:

     1. requestCode 表示 PendingIntent 發(fā)送方的請(qǐng)求碼宋列,多數(shù)情況下設(shè)置 0 即可昭抒,另外 requestCode 會(huì)影響到 flags 的效果。
     2. flags 參數(shù):
        1. **FLAG_ONE_SHOP** 當(dāng)前的PendingIntent只能被使用一次,然后他就會(huì)自動(dòng)cancel灭返,如果后續(xù)還有相同的PendingIntent盗迟,那么它們的send方法就會(huì)調(diào)用失敗。
        2. **FLAG_NO_CREATE** 當(dāng)前描述的PendingIntent不會(huì)主動(dòng)創(chuàng)建婆殿,如果當(dāng)前PendingIntent之前存在诈乒,那么getActivity、getService和getBroadcast方法會(huì)直接返回Null婆芦,即獲取PendingIntent失敗怕磨,無(wú)法單獨(dú)使用,平時(shí)很少用到消约。
        3. **FLAG_CANCEL_CURRENT** 當(dāng)前描述的PendingIntent如果已經(jīng)存在肠鲫,那么它們都會(huì)被cancel,然后系統(tǒng)會(huì)創(chuàng)建一個(gè)新的PendingIntent或粮。對(duì)于通知欄消息來(lái)說(shuō)导饲,那些被cancel的消息單擊后無(wú)法打開(kāi)。
        4. **FLAG_UPDATE_CURRENT** 當(dāng)前描述的PendingIntent如果已經(jīng)存在氯材,那么它們都會(huì)被更新渣锦,即它們的Intent中的Extras會(huì)被替換為最新的。
  1. 匹配規(guī)則

    1. 如果兩個(gè) PendingIntent 內(nèi)部的 Intent 相同且 requestCode 也相同氢哮,那么二者相同
    2. Intent 相同的匹配規(guī)則:Intent 的 ComponentName 和 intent-filter 都相同袋毙。Extras 不參與 Intent的匹配過(guò)程。

RemoteView 的內(nèi)部機(jī)制

  1. 構(gòu)造方法 public RemoteViews(String packageName, int layoutId)

    參數(shù)說(shuō)明:

    1. packageName:當(dāng)前應(yīng)用的包名
    2. layoutId:待加載的布局文件
  2. 限制 -> 支持的 View 類(lèi)型有限

    1. LayoutFrameLayout冗尤,LineanLayout听盖,RelativeLayoutGridLayout
    2. ViewAnalogClock裂七,Button皆看,ChronometerImageButton背零,ImageView腰吟,ProgressBarTextView徙瓶,ViewFlipper蝎困,ListViewGridView倍啥,StackView禾乘,AdapterViewFlipperViewStub
  3. 特殊之處

    1. RemoteView 沒(méi)有提供 findViewById 方法虽缕,因此無(wú)法直接訪問(wèn)里面的 View 元素始藕,而必須通過(guò) RemoteViews 所提供的一些列 set 方法來(lái)完成,這時(shí)因?yàn)?RemoteView 在遠(yuǎn)程進(jìn)程中顯示
    2. 一系列 set 方法 是通過(guò)反射來(lái)完成的。
  4. 工作流程

    1. 前置:通知欄和桌面小部件分別由 NotificationManager 和 AppWidgetManager 管理伍派,而 NotificationManager 和 AppWidgetManager 通過(guò) Binder 分別和 SystemServer 進(jìn)程中的 NotificationManagerService(NMS) 以及 AppWidgetService(AWS) 進(jìn)行通信江耀。布局文件實(shí)際是在 NMS 和 AWS 中被加載的,而運(yùn)行在 SystemServer 中诉植,這就和我們的進(jìn)程構(gòu)成了 跨進(jìn)程通信 的場(chǎng)景祥国。

    2. 具體流程

      1. 首先 RemoteViews 通過(guò) Binder 傳遞到 System Server 進(jìn)程(RemoteViews 實(shí)現(xiàn)了 Parcelable 接口)。系統(tǒng)會(huì)根據(jù) RemoteViews 中的包名等信息去得到該應(yīng)用的資源晾腔。

      2. 然后通過(guò) LayoutInflater 去加載 RemoteViews 中的布局文件舌稀。(對(duì)于 SystemServer 進(jìn)程來(lái)講,加載的只是一個(gè)普通的 view灼擂,只不過(guò)對(duì)于我們的進(jìn)程來(lái)講是 遠(yuǎn)程的)

      3. 接著系統(tǒng)對(duì) View 執(zhí)行一系列界面更新任務(wù)壁查,這些任務(wù)通過(guò) set 方法來(lái)提交。這些更新不是立刻執(zhí)行剔应,而是在 RemoteViews 中記錄所有更新操作睡腿,等到 RemoteViews 被加載以后才能執(zhí)行。

        到此時(shí)峻贮,RemoteViews 就可以在 SystemServer 進(jìn)程中顯示了席怪。

      4. 當(dāng)需要更新 RemoteViews 時(shí),調(diào)用一些列 set 方法并通過(guò) NotificationManager 和 AppWidgetManager 來(lái)提交更新任務(wù)纤控,具體操作也是在 SystemServer 進(jìn)程中完成挂捻。

    3. 進(jìn)一步說(shuō)明 -- 跨進(jìn)程

      1. 系統(tǒng)不直接通過(guò) Binder 支持所有的 View 和 View 操作,否則 View 的方法龐大嚼黔,同時(shí) IPC 操作會(huì)影響效率
      2. 系統(tǒng)提供了一個(gè) Action 概念, Action 實(shí)現(xiàn)了 Parcelable 接口惜辑,代表一個(gè) View 操作唬涧。
      3. 系統(tǒng)首先將 View 操作封裝到 Action 對(duì)象并將這些對(duì)象跨進(jìn)程傳輸?shù)竭h(yuǎn)程進(jìn)程,接著在遠(yuǎn)程進(jìn)程中執(zhí)行 Action 對(duì)象中的具體操作盛撑。遠(yuǎn)程進(jìn)程通過(guò) RemoteViews 的 apply 方法來(lái)進(jìn)行 View 的更新操作碎节,Remoteview 的 apply 方法內(nèi)部會(huì)遍歷所有的 Action 對(duì)象并調(diào)用它們的 apply 方法,進(jìn)而執(zhí)行具體的 View 的更新操作抵卫。
      4. 此方法避免了 定義大量的 Binder 接口狮荔,其次通過(guò)遠(yuǎn)程進(jìn)程中批量執(zhí)行修改擦歐總避免了大量 IPC 操作。
    4. 源碼說(shuō)明:

      1. 見(jiàn)原書(shū)吧介粘。殖氏。
    5. 補(bǔ)充說(shuō)明

      1. apply 和 reApply 的區(qū)別:前者會(huì)加載布局并更新界面,后者只會(huì)更新界面
      2. 關(guān)于點(diǎn)擊事件姻采。RemoteViews 中只支持發(fā)起 PendingIntent 不支持 onClickListener 那種模式雅采。另外, setOnClickPendingIntent 用于給普通 View 設(shè)置點(diǎn)擊事件,不能給集合(ListView / StackvView)中的 View 設(shè)置點(diǎn)擊事件婚瓜。如果要給 ListView / StackvView 中的 itemview 設(shè)置單擊事件宝鼓,必須將 setPendingIntentTemplate 和 setOnClickFillInIntent 組合使用才可以。

RemoteViews 的意義

  1. 從字面上就能猜到:RemoteViews 目的就是為了方便的更新遠(yuǎn)程 views 巴刻,即跨進(jìn)程更新 UI

    1. 當(dāng)一個(gè)應(yīng)用需要能夠更新另一個(gè)應(yīng)用中的某個(gè)界面愚铡,這時(shí)候如果通過(guò) AIDL實(shí)現(xiàn),那么可能會(huì)隨著界面更新操作的復(fù)雜導(dǎo)致效率變低胡陪。這種場(chǎng)景就很適合使用 RemoteViews沥寥。

    2. RemoteViews 缺點(diǎn)在于 它只支持一些常見(jiàn)的 View,不支持自定義 View督弓。

    3. 布局文件的加載問(wèn)題

      1. 同一個(gè)應(yīng)用的多進(jìn)程情形

        View view = remoteViews.apply(this,mRemoteViewsContent);
        mRemoteViewsContent.addView(view);
        
      2. 不同應(yīng)用時(shí)

        主要是由于兩個(gè)應(yīng)用的資源 ID 不一定一致营曼,因此通過(guò)資源名稱(chēng)來(lái)加載布局文件

        int layoutId = getResources().getIdentifier("layout_simulated_notification","layout",getPackageName());
        view view = getLayoutInflater().inflate(layoutId,mRemoteViewsContent,flase);
        remoteViews.reapply(this,view);
        mRemoteViewsContent.addView(view);
        
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市愚隧,隨后出現(xiàn)的幾起案子蒂阱,更是在濱河造成了極大的恐慌,老刑警劉巖狂塘,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件录煤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡荞胡,警方通過(guò)查閱死者的電腦和手機(jī)妈踊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)泪漂,“玉大人廊营,你說(shuō)我怎么就攤上這事÷芮冢” “怎么了露筒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)敌卓。 經(jīng)常有香客問(wèn)我慎式,道長(zhǎng),這世上最難降的妖魔是什么趟径? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任瘪吏,我火速辦了婚禮,結(jié)果婚禮上蜗巧,老公的妹妹穿的比我還像新娘掌眠。我一直安慰自己,他們只是感情好幕屹,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布扇救。 她就那樣靜靜地躺著刑枝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪迅腔。 梳的紋絲不亂的頭發(fā)上装畅,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音沧烈,去河邊找鬼掠兄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锌雀,可吹牛的內(nèi)容都是我干的蚂夕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼腋逆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼婿牍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起惩歉,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤等脂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后撑蚌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體上遥,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年争涌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了粉楚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡亮垫,死狀恐怖模软,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情饮潦,我是刑警寧澤燃异,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站害晦,受9級(jí)特大地震影響特铝,放射性物質(zhì)發(fā)生泄漏暑中。R本人自食惡果不足惜壹瘟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鳄逾。 院中可真熱鬧稻轨,春花似錦、人聲如沸雕凹。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至线欲,卻和暖如春明场,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背李丰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工苦锨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趴泌。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓舟舒,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親嗜憔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子秃励,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 今天聽(tīng)曾仕強(qiáng)教授講解《論語(yǔ)》中“知之為知之,不知為不知吉捶,是知也”時(shí)夺鲜,講了個(gè)故事,首先解釋下“知之為知之帚稠,不知為不知...
    o鹿鳴閱讀 279評(píng)論 1 2
  • 《吉檀迦利》在剛開(kāi)始學(xué)的時(shí)候谣旁,懵懵懂懂,應(yīng)付著學(xué)下去滋早,不懂得它的真正含義榄审,許多比喻都看不出來(lái)本體。因?yàn)樵趧傞_(kāi)...
    崔禹喆閱讀 221評(píng)論 1 1
  • 踏足那會(huì)兒,正是隆冬 深夜的夢(mèng)昔头,全都是不安的躁動(dòng) 寒風(fēng)還肆虐的時(shí)候饼问,你就坐上火車(chē) 趕著離開(kāi)了,這么久 這么遠(yuǎn)的路揭斧,...
    洛城未晞閱讀 188評(píng)論 0 1
  • 以前真的不能體會(huì)農(nóng)民對(duì)土地的愛(ài)莱革,因?yàn)樘锏亟o我的記憶不深,并隨著年齡的成長(zhǎng)離我越來(lái)越遠(yuǎn)讹开。一片只是能種點(diǎn)東西的土盅视,...
    54小愈閱讀 185評(píng)論 0 0