什么是Json?
Json(javascript Object Notation):Javascript對(duì)象表示法。是一種輕量級(jí)的數(shù)據(jù)交換格式,相比于xml這種數(shù)據(jù)交換格式來(lái)說(shuō),因?yàn)榻馕鰔ml比較的復(fù)雜,而且需要編寫(xiě)大段的代碼,所以客戶(hù)端和服務(wù)器的數(shù)據(jù)交換格式往往通過(guò)Json來(lái)進(jìn)行交換。
Json一共有兩種數(shù)據(jù)結(jié)構(gòu):
1、一種是以 (key/value)對(duì)形式存在的無(wú)序的jsonObject對(duì)象,一個(gè)對(duì)象以“{”(左花括號(hào))開(kāi)始,“}”(右花括號(hào))結(jié)束。每個(gè)“名稱(chēng)”后跟一個(gè)“:”(冒號(hào));“‘名稱(chēng)/值’ 對(duì)”之間使用“,”(逗號(hào))分隔。
2、另一種數(shù)據(jù)格式就是有序的value的集合,這種形式被稱(chēng)為是jsonArray集合,數(shù)組是值(value)的有序集合。一個(gè)數(shù)組以“[”(左中括號(hào))開(kāi)始,“]”(右中括號(hào))結(jié)束。值之間使用“,”(逗號(hào))分隔。
{}雙括號(hào)表示對(duì)象;
[]中括號(hào)表示數(shù)組;
" " 雙引號(hào)內(nèi)是屬性或值;
: 冒號(hào)表示后者是前者的值(這個(gè)值可以是字符串、數(shù)字、也可以是另一個(gè)數(shù)組或?qū)ο?;
所以 {"name": "Michael"} 可以理解為是一個(gè)包含name為Michael的對(duì)象;
而[{"name": "Michael"},{"name": "Jerry"}]就表示包含兩個(gè)對(duì)象的數(shù)組。當(dāng)然了,你也可以使用{"name":["Michael","Jerry"]}來(lái)簡(jiǎn)化上面一部,這是一個(gè)擁有一個(gè)name數(shù)組的對(duì)象。
下面通過(guò)解析Json的三種方式來(lái)實(shí)現(xiàn)在Android客戶(hù)端和服務(wù)器端使用json這種數(shù)據(jù)格式來(lái)進(jìn)行數(shù)據(jù)的交換。
一、解析JSON之使用原生態(tài)解析
Android客戶(hù)端通過(guò)一個(gè)AsyncTask異步任務(wù)請(qǐng)求服務(wù)器端的某些數(shù)據(jù),AsyncTask兩個(gè)方法(1)獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground();(2)更新UI(數(shù)據(jù)):onPostExecute()。在解析完這些數(shù)據(jù)后,onPostExecute()方法會(huì)將解析的數(shù)據(jù)內(nèi)容更新到適配器,通知適配器發(fā)送改變。代碼注釋如下:
public class JsonActivity extends AppCompatActivity { PRivate ListView lv_main_jsondata; private List<UserEntity> list=new ArrayList<>();//定義一個(gè)對(duì)象集合 private ProgressDialog progress; private JsonActivity.myAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_json); lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//獲取listview控件 myAdapter = new myAdapter();//實(shí)列化對(duì)象 //給listview一個(gè)適配器,需要自己寫(xiě)一個(gè)類(lèi)繼承BaseAdapter lv_main_jsondata.setAdapter(myAdapter); //增加動(dòng)畫(huà)加載效果 progress = new ProgressDialog(this); progress.setMessage("locating.....");//獲取動(dòng)畫(huà)加載消息內(nèi)容 } //1、寫(xiě)一個(gè)類(lèi)繼承BaseAdapter,重寫(xiě)它的四個(gè)方法class myAdapter extends BaseAdapter{ @Override public int getCount() {//獲取總數(shù)量 return list.size(); } @Override public Object getItem(int position) {//獲取當(dāng)前位置 return list.get(position); } @Override public long getItemId(int position) {//獲取當(dāng)前位置的ID return position; } @Override public View getView(int position, View convertView, ViewGroup parent) {//獲取視圖 if (convertView==null){ convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity();//實(shí)列化一個(gè)對(duì)象 //將對(duì)象的屬性增加到相對(duì)應(yīng)的控件中 activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one); activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity);//獲取標(biāo)簽 } DomActivity domActivity= (DomActivity) convertView.getTag();//通過(guò)convertView得到標(biāo)簽 //獲取對(duì)象的屬性,將每個(gè)屬性增加到它相對(duì)應(yīng)的位置 domActivity.uname.setText(list.get(position).getUname()); domActivity.content.setText(list.get(position).getContent()); domActivity.anthour.setText(list.get(position).getAnthour()); return convertView; }} //獲取Json數(shù)據(jù) public void getjson(View view){ progress.show();//更新數(shù)據(jù)之前增加動(dòng)畫(huà)加載 new myTask().execute(); } //1、寫(xiě)一個(gè)類(lèi)繼承AsyncTask,重寫(xiě)它的兩個(gè)方法 // <1、獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground // <2、更新UI(數(shù)據(jù)):onPostExecute class myTask extends AsyncTask{ private StringBuffer stringBuffer; //獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground @Override protected Object doInBackground(Object[] params) { //(1)、獲得數(shù)據(jù)路徑 String path=getString(R.string.path)+"android_json.xhtml"; try { //(2)、實(shí)例化url:將獲取網(wǎng)絡(luò)數(shù)據(jù)的路徑放到URL中。 URL url=new URL(path); //(3)/通過(guò)URL獲取連接的對(duì)象 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(); //(4)、設(shè)置參數(shù) 01請(qǐng)求的方式:1、get;2、post; 02設(shè)置請(qǐng)求時(shí)間 httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(5000); //(5)、判斷響應(yīng)碼是否是200 是的話就請(qǐng)求到數(shù)據(jù) if (httpURLConnection.getResponseCode()==200){//如果請(qǐng)求到的響應(yīng)碼是200 那么就要去讀取它的數(shù)據(jù) InputStream inputStream=httpURLConnection.getInputStream();//以字節(jié)流的形式得到數(shù)據(jù) //通過(guò)字符流(bufferedread)的形式讀取數(shù)據(jù) BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//將字符流轉(zhuǎn)成字節(jié)流 //實(shí)列化一個(gè)對(duì)象 stringBuffer = new StringBuffer(); String str=null;//定義一個(gè)接收的字符串 while((str=bufferedReader.readLine())!=null){//字符流讀取數(shù)據(jù)不為空 stringBuffer.append(str);//把字符流讀取的數(shù)據(jù)增加到對(duì)象中 } Log.i("test", "doInBackground: "+ stringBuffer.toString()); } //解析JSON try { // 一、使用原生態(tài)解析 //1、通過(guò)jsonobject對(duì)象獲取數(shù)據(jù) JSONObject jsonObject=new JSONObject(stringBuffer.toString()); //2、獲取數(shù)據(jù)的屬性 String clazz=jsonObject.getString("class"); Log.i("test", "doInBackground: "+clazz); int munber=jsonObject.getInt("lists");//獲取它的數(shù)量 Log.i("test", "doInBackground: "+munber); //3、獲取集合的屬性 JSONArray array= jsonObject.getJSONArray("fqs"); for (int i = 0; i <array.length() ; i++) {//循環(huán)獲取array的長(zhǎng)度 JSONObject object= array.getJSONObject(i);//拿到每一個(gè)對(duì)象 //通過(guò)對(duì)象獲取每個(gè)屬性 String name=object.getString("name"); String content=object.getString("content"); String anthour=object.getString("anthour"); UserEntity user=new UserEntity(name,content,anthour);//實(shí)列化一個(gè)對(duì)象,每循環(huán)一次實(shí)列化一次 list.add(user); } } catch (JSONException e) { e.printStackTrace(); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }//更新UI(數(shù)據(jù)):onPostExecute @Override protected void onPostExecute(Object o) { myAdapter.notifyDataSetChanged();//通知適配器數(shù)據(jù)發(fā)生改變 progress.cancel();//動(dòng)畫(huà)取消 super.onPostExecute(o); } }}二、解析JSON之GSON解析
使用Gson解析需要去下載Gson這個(gè)jar包,導(dǎo)入到我們的項(xiàng)目中。用Gson,我們可以非常輕松的實(shí)現(xiàn)數(shù)據(jù)對(duì)象和json對(duì)象的相互轉(zhuǎn)化,其中我們最常用的方法fromJSON(),將json對(duì)象轉(zhuǎn)換成我們需要的數(shù)據(jù)對(duì)象。代碼注釋如下:
public class JsonActivity extends AppCompatActivity { private ListView lv_main_jsondata; private List<UserEntity> list=new ArrayList<>();//定義一個(gè)對(duì)象集合 private ProgressDialog progress; private JsonActivity.myAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_json); lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//獲取listview控件 myAdapter = new myAdapter();//實(shí)列化對(duì)象 //給listview一個(gè)適配器,需要自己寫(xiě)一個(gè)類(lèi)繼承BaseAdapter lv_main_jsondata.setAdapter(myAdapter); //增加動(dòng)畫(huà)加載效果 progress = new ProgressDialog(this); progress.setMessage("locating.....");//獲取動(dòng)畫(huà)加載消息內(nèi)容 } //1、寫(xiě)一個(gè)類(lèi)繼承BaseAdapter,重寫(xiě)它的四個(gè)方法class myAdapter extends BaseAdapter{ @Override public int getCount() {//獲取總數(shù)量 return list.size(); } @Override public Object getItem(int position) {//獲取當(dāng)前位置 return list.get(position); } @Override public long getItemId(int position) {//獲取當(dāng)前位置的ID return position; } @Override public View getView(int position, View convertView, ViewGroup parent) {//獲取視圖 if (convertView==null){ convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity();//實(shí)列化一個(gè)對(duì)象 //將對(duì)象的屬性增加到相對(duì)應(yīng)的控件中 activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one); activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity);//獲取標(biāo)簽 } DomActivity domActivity= (DomActivity) convertView.getTag();//通過(guò)convertView得到標(biāo)簽 //獲取對(duì)象的屬性,將每個(gè)屬性增加到它相對(duì)應(yīng)的位置 domActivity.uname.setText(list.get(position).getUname()); domActivity.content.setText(list.get(position).getContent()); domActivity.anthour.setText(list.get(position).getAnthour()); return convertView; }} //獲取Json數(shù)據(jù) public void getjson(View view){ progress.show();//更新數(shù)據(jù)之前增加動(dòng)畫(huà)加載 new myTask().execute(); } //1、寫(xiě)一個(gè)類(lèi)繼承AsyncTask,重寫(xiě)它的兩個(gè)方法 // <1、獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground // <2、更新UI(數(shù)據(jù)):onPostExecute class myTask extends AsyncTask{ private StringBuffer stringBuffer; //獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground @Override protected Object doInBackground(Object[] params) { //(1)、獲得數(shù)據(jù)路徑 String path=getString(R.string.path)+"android_json.xhtml"; try { //(2)、實(shí)例化url:將獲取網(wǎng)絡(luò)數(shù)據(jù)的路徑放到URL中。 URL url=new URL(path); //(3)/通過(guò)URL獲取連接的對(duì)象 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(); //(4)、設(shè)置參數(shù) 01請(qǐng)求的方式:1、get;2、post; 02設(shè)置請(qǐng)求時(shí)間 httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(5000); //(5)、判斷響應(yīng)碼是否是200 是的話就請(qǐng)求到數(shù)據(jù) if (httpURLConnection.getResponseCode()==200){//如果請(qǐng)求到的響應(yīng)碼是200 那么就要去讀取它的數(shù)據(jù) InputStream inputStream=httpURLConnection.getInputStream();//以字節(jié)流的形式得到數(shù)據(jù) //通過(guò)字符流(bufferedread)的形式讀取數(shù)據(jù) BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//將字符流轉(zhuǎn)成字節(jié)流 //實(shí)列化一個(gè)對(duì)象 stringBuffer = new StringBuffer(); String str=null;//定義一個(gè)接收的字符串 while((str=bufferedReader.readLine())!=null){//字符流讀取數(shù)據(jù)不為空 stringBuffer.append(str);//把字符流讀取的數(shù)據(jù)增加到對(duì)象中 } Log.i("test", "doInBackground: "+ stringBuffer.toString()); } //解析JSON //二、使用Gson解析Json Gson gson=new Gson();//實(shí)列化一個(gè)對(duì)象 //通過(guò)gson解析一個(gè)對(duì)象,將buffered流解析到a對(duì)象中 BigjsonActivity bjson=gson.fromJson(stringBuffer.toString(),BigjsonActivity.class); //通過(guò)對(duì)象獲取這個(gè)對(duì)象中相對(duì)應(yīng)的屬性 String clazz=bjson.getClazz(); int munber=bjson.getLists(); Log.i("test", "doInBackground: "+clazz+" ;"+munber); list.addAll(bjson.getListuser());//將對(duì)象中的集合放入list對(duì)象集合中 } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }//更新UI(數(shù)據(jù)):onPostExecute @Override protected void onPostExecute(Object o) { myAdapter.notifyDataSetChanged();//通知適配器數(shù)據(jù)發(fā)生改變 progress.cancel();//動(dòng)畫(huà)取消 super.onPostExecute(o); } }}三、解析JSON之FastJson解析
使用FastJson需要導(dǎo)入第三方包,用法和Gson一樣,實(shí)現(xiàn)數(shù)據(jù)對(duì)象和json對(duì)象的相互轉(zhuǎn)化Gson是用fromJSON()方法,而FastJson用JSON.parSEObject()方法,然后將json對(duì)象中的集合放入我們需要的數(shù)據(jù)對(duì)象集合中。代碼注釋如下:
public class JsonActivity extends AppCompatActivity { private ListView lv_main_jsondata; private List<UserEntity> list=new ArrayList<>();//定義一個(gè)對(duì)象集合 private ProgressDialog progress; private JsonActivity.myAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_json); lv_main_jsondata = (ListView) findViewById(R.id.lv_main_jsondata);//獲取listview控件 myAdapter = new myAdapter();//實(shí)列化對(duì)象 //給listview一個(gè)適配器,需要自己寫(xiě)一個(gè)類(lèi)繼承BaseAdapter lv_main_jsondata.setAdapter(myAdapter); //增加動(dòng)畫(huà)加載效果 progress = new ProgressDialog(this); progress.setMessage("locating.....");//獲取動(dòng)畫(huà)加載消息內(nèi)容 } //1、寫(xiě)一個(gè)類(lèi)繼承BaseAdapter,重寫(xiě)它的四個(gè)方法class myAdapter extends BaseAdapter{ @Override public int getCount() {//獲取總數(shù)量 return list.size(); } @Override public Object getItem(int position) {//獲取當(dāng)前位置 return list.get(position); } @Override public long getItemId(int position) {//獲取當(dāng)前位置的ID return position; } @Override public View getView(int position, View convertView, ViewGroup parent) {//獲取視圖 if (convertView==null){ convertView= LayoutInflater.from(JsonActivity.this).inflate(R.layout.dom_listview,null); DomActivity activity=new DomActivity();//實(shí)列化一個(gè)對(duì)象 //將對(duì)象的屬性增加到相對(duì)應(yīng)的控件中 activity.uname= (TextView) convertView.findViewById(R.id.tv_listview_one); activity.content= (TextView) convertView.findViewById(R.id.tv_listview_two); activity.anthour= (TextView) convertView.findViewById(R.id.tv_listview_three); convertView.setTag(activity);//獲取標(biāo)簽 } DomActivity domActivity= (DomActivity) convertView.getTag();//通過(guò)convertView得到標(biāo)簽 //獲取對(duì)象的屬性,將每個(gè)屬性增加到它相對(duì)應(yīng)的位置 domActivity.uname.setText(list.get(position).getUname()); domActivity.content.setText(list.get(position).getContent()); domActivity.anthour.setText(list.get(position).getAnthour()); return convertView; }} //獲取Json數(shù)據(jù) public void getjson(View view){ progress.show();//更新數(shù)據(jù)之前增加動(dòng)畫(huà)加載 new myTask().execute(); } //1、寫(xiě)一個(gè)類(lèi)繼承AsyncTask,重寫(xiě)它的兩個(gè)方法 // <1、獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground // <2、更新UI(數(shù)據(jù)):onPostExecute class myTask extends AsyncTask{ private StringBuffer stringBuffer; //獲取網(wǎng)絡(luò)數(shù)據(jù):doInBackground @Override protected Object doInBackground(Object[] params) { //(1)、獲得數(shù)據(jù)路徑 String path=getString(R.string.path)+"android_json.xhtml"; try { //(2)、實(shí)例化url:將獲取網(wǎng)絡(luò)數(shù)據(jù)的路徑放到URL中。 URL url=new URL(path); //(3)/通過(guò)URL獲取連接的對(duì)象 HttpURLConnection httpURLConnection= (HttpURLConnection) url.openConnection(); //(4)、設(shè)置參數(shù) 01請(qǐng)求的方式:1、get;2、post; 02設(shè)置請(qǐng)求時(shí)間 httpURLConnection.setRequestMethod("GET"); httpURLConnection.setConnectTimeout(5000); //(5)、判斷響應(yīng)碼是否是200 是的話就請(qǐng)求到數(shù)據(jù) if (httpURLConnection.getResponseCode()==200){//如果請(qǐng)求到的響應(yīng)碼是200 那么就要去讀取它的數(shù)據(jù) InputStream inputStream=httpURLConnection.getInputStream();//以字節(jié)流的形式得到數(shù)據(jù) //通過(guò)字符流(bufferedread)的形式讀取數(shù)據(jù) BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));//將字符流轉(zhuǎn)成字節(jié)流 //實(shí)列化一個(gè)對(duì)象 stringBuffer = new StringBuffer(); String str=null;//定義一個(gè)接收的字符串 while((str=bufferedReader.readLine())!=null){//字符流讀取數(shù)據(jù)不為空 stringBuffer.append(str);//把字符流讀取的數(shù)據(jù)增加到對(duì)象中 } Log.i("test", "doInBackground: "+ stringBuffer.toString()); } //解析JSON //三、使用FsatJson解析 //通過(guò)json解析一個(gè)對(duì)象,將buffered流解析到對(duì)象中 BigjsonActivity bjson =JSON.parseObject(stringBuffer.toString(),BigjsonActivity.class); //通過(guò)對(duì)象獲取這個(gè)對(duì)象中相對(duì)應(yīng)的屬性 String clazz=bjson.getClazz(); int munber=bjson.getLists(); Log.i("test", "doInBackground: "+clazz+" ;"+munber); list.addAll(bjson.getFqs());//將對(duì)象中的集合放入list對(duì)象集合中 } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }//更新UI(數(shù)據(jù)):onPostExecute @Override protected void onPostExecute(Object o) { myAdapter.notifyDataSetChanged();//通知適配器數(shù)據(jù)發(fā)生改變 progress.cancel();//動(dòng)畫(huà)取消 super.onPostExecute(o); } }} 總結(jié): JSON對(duì)于移動(dòng)設(shè)備來(lái)說(shuō),尤其對(duì)于網(wǎng)絡(luò)環(huán)境較差和流量限制的情況下,相對(duì)于XML格式的數(shù)據(jù)傳輸會(huì)更節(jié)省流量,傳輸效率更高。在這三種解析方式中FastJson是效率最高的。
Android的JSON解析部分都在包org.json下,主要有以下幾個(gè)類(lèi):
《1、JSONObject:可以看作是一個(gè)json對(duì)象,這是系統(tǒng)中有關(guān)JSON定義的基本單元,其包含一對(duì)兒(Key/Value)數(shù)值。它對(duì)外部(External:應(yīng)用toString()方法輸出的數(shù)值)調(diào)用的響應(yīng)體現(xiàn)為一個(gè)標(biāo)準(zhǔn)的字符串(例如:{"JSON": "Hello, World"},最外被大括號(hào)包裹,其中的Key和Value被冒號(hào)":"分隔)。其對(duì)于內(nèi)部(Internal)行為的操作格式略微,例如:初始化一個(gè)JSONObject實(shí)例,引用內(nèi)部的put()方法添加數(shù)值:new JSONObject().put("JSON", "Hello, World!"),在Key和Value之間是以逗號(hào)","分隔。Value的類(lèi)型包括:Boolean、JSONArray、JSONObject、Number、String或者默認(rèn)值JSONObject.NULL object。《2、JSONStringer:json文本構(gòu)建類(lèi) ,根據(jù)官方的解釋?zhuān)@個(gè)類(lèi)可以幫助快速和便捷的創(chuàng)建JSON text。其最大的優(yōu)點(diǎn)在于可以減少由于 格式的錯(cuò)誤導(dǎo)致程序異常,引用這個(gè)類(lèi)可以自動(dòng)嚴(yán)格按照J(rèn)SON語(yǔ)法規(guī)則(syntax rules)創(chuàng)建JSON text。每個(gè)JSONStringer實(shí)體只能對(duì)應(yīng)創(chuàng)建一個(gè)JSON text。。其最大的優(yōu)點(diǎn)在于可以減少由于格式的錯(cuò)誤導(dǎo)致程序異常,引用這個(gè)類(lèi)可以自動(dòng)嚴(yán)格按照J(rèn)SON語(yǔ)法規(guī)則(syntax rules)創(chuàng)建JSON text。每個(gè)JSONStringer實(shí)體只能對(duì)應(yīng)創(chuàng)建一個(gè)JSON text?!?、JSONArray:它代表一組有序的數(shù)值。將其轉(zhuǎn)換為String輸出(toString)所表現(xiàn)的形式是用方括號(hào)包裹,數(shù)值以逗號(hào)”,”分隔(例如:[value1,value2,value3],大家可以親自利用簡(jiǎn)短的代碼更加直觀的了解其格式)。這個(gè)類(lèi)的內(nèi)部同樣具有查詢(xún)行為,get()和opt()兩種方法都可以通過(guò)index索引返回指定的數(shù)值,put()方法用來(lái)添加或者替換數(shù)值。同樣這個(gè)類(lèi)的value類(lèi)型可以包括:Boolean、JSONArray、JSONObject、Number、String或者默認(rèn)JSONObject.NULL object?!?、JSONTokener:json解析類(lèi)。
《5、JSONException:json中用到的異常
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注