【问题标题】:How can I parse a local JSON file from assets folder into a ListView?如何将资产文件夹中的本地 JSON 文件解析为 ListView?
【发布时间】:2013-11-25 13:26:44
【问题描述】:

我目前正在开发一个物理应用程序,它应该显示一个公式列表,甚至解决其中的一些问题(唯一的问题是 ListView

这是我的主要布局

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:measureWithLargestChild="false"
    android:orientation="vertical"
    tools:context=".CatList" >


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/titlebar" >

        <TextView
            android:id="@+id/Title1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="@string/app_name"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="#ff1c00"
            android:textIsSelectable="false" />

    </RelativeLayout>

    <ListView
        android:id="@+id/listFormulas"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

    </ListView>

</LinearLayout>

这是我的主要活动

package com.wildsushii.quickphysics;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetManager;
import android.view.Menu;
import android.widget.ListView;

public class CatList extends Activity {



    public static String AssetJSONFile (String filename, Context context) throws IOException {
        AssetManager manager = context.getAssets();
        InputStream file = manager.open(filename);
        byte[] formArray = new byte[file.available()];
        file.read(formArray);
        file.close();

        return new String(formArray);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cat_list);
        ListView categoriesL = (ListView)findViewById(R.id.listFormulas);

        ArrayList<HashMap<String, String>> formList = new ArrayList<HashMap<String, String>>();
        Context context = null;
        try {
            String jsonLocation = AssetJSONFile("formules.json", context);
            JSONObject formArray = (new JSONObject()).getJSONObject("formules");
            String formule = formArray.getString("formule");
            String url = formArray.getString("url");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

        //My problem is here!!
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.cat_list, menu);
        return true;
    }
}

我实际上知道我可以在不使用 JSON 的情况下做到这一点,但我需要更多练习解析 JSON。顺便说一句,这是 JSON

    {
    "formules": [
    {
      "formule": "Linear Motion",
      "url": "qp1"
    },
    {
      "formule": "Constant Acceleration Motion",
      "url": "qp2"
    },
    {
      "formule": "Projectile Motion",
      "url": "qp3"
    },
    {
      "formule": "Force",
      "url": "qp4"
    },
    {
      "formule": "Work, Power, Energy",
      "url": "qp5"
    },
    {
      "formule": "Rotary Motion",
      "url": "qp6"
    },
    {
      "formule": "Harmonic Motion",
      "url": "qp7"
    },
    {
      "formule": "Gravity",
      "url": "qp8"
    },
    {
      "formule": "Lateral and Longitudinal Waves",
      "url": "qp9"
    },
    {
      "formule": "Sound Waves",
      "url": "qp10"
    },
    {
      "formule": "Electrostatics",
      "url": "qp11"
    },
    {
      "formule": "Direct Current",
      "url": "qp12"
    },
    {
      "formule": "Magnetic Field",
      "url": "qp13"
    },
    {
      "formule": "Alternating Current",
      "url": "qp14"
    },
    {
      "formule": "Thermodynamics",
      "url": "qp15"
    },
    {
      "formule": "Hydrogen Atom",
      "url": "qp16"
    },
    {
      "formule": "Optics",
      "url": "qp17"
    },
    {
      "formule": "Modern Physics",
      "url": "qp18"
    },
    {
      "formule": "Hydrostatics",
      "url": "qp19"
    },
    {
      "formule": "Astronomy",
      "url": "qp20"
    }
  ]
}

我尝试了很多东西,甚至删除了整个项目重新创建一个:(

【问题讨论】:

标签: java android json android-listview local


【解决方案1】:

正如 Faizan 在their answer here 中描述的那样:

首先使用以下代码从您的评估文件中读取 Json 文件。

然后您可以简单地将这个函数返回的字符串读取为

public String loadJSONFromAsset() {
    String json = null;
    try {
        InputStream is = getActivity().getAssets().open("yourfilename.json");
        int size = is.available();
        byte[] buffer = new byte[size];
        is.read(buffer);
        is.close();
        json = new String(buffer, "UTF-8");
    } catch (IOException ex) {
        ex.printStackTrace();
        return null;
    }
    return json;
}

然后像这样使用这个方法

    try {
        JSONObject obj = new JSONObject(loadJSONFromAsset());
        JSONArray m_jArry = obj.getJSONArray("formules");
        ArrayList<HashMap<String, String>> formList = new ArrayList<HashMap<String, String>>();
        HashMap<String, String> m_li;

        for (int i = 0; i < m_jArry.length(); i++) {
            JSONObject jo_inside = m_jArry.getJSONObject(i);
            Log.d("Details-->", jo_inside.getString("formule"));
            String formula_value = jo_inside.getString("formule");
            String url_value = jo_inside.getString("url");

            //Add your values in your `ArrayList` as below:
            m_li = new HashMap<String, String>();
            m_li.put("formule", formula_value);
            m_li.put("url", url_value);

            formList.add(m_li);
        }
    } catch (JSONException e) {
        e.printStackTrace();
    }

有关 JSON 的更多详细信息Read HERE

【讨论】:

  • op 从 assests 文件夹中读取的内容很好,他将 null 作为上下文传递。 m_li.put("formula", formula); 也应该是 m_li.put("formula", formula_value); 并且应该使用 Log 而不是 System.out.println
  • @Raghunandan 感谢您的建议。我已经更新了我的答案。 :)
  • 根据 Java 文档,根据 available() 返回的结果分配缓冲区是不正确的:docs.oracle.com/javase/7/docs/api/java/io/…“请注意,虽然 InputStream 的某些实现将返回流中的总字节数,很多人不会。使用此方法的返回值来分配旨在保存此流中所有数据的缓冲区是不正确的。"
  • 尽管这是一个老问题,但由于这是最佳答案@GrIsHu,您能否考虑更新您的答案?
  • 我知道这是一个旧线程,但是有没有人在不使用 InputStream.available() 的情况下找到可行的解决方案?我找到的每个解决方案都包含它。
【解决方案2】:

Kotlin 有这个扩展函数来读取文件返回为字符串。

fun AssetManager.readAssetsFile(fileName : String): String = open(fileName).bufferedReader().use{it.readText()}

使用任何 JSON 解析器解析输出字符串。

【讨论】:

  • 你能添加一个完整的代码示例如何实际解析 json
  • 感谢您的回答。它对我有用,并添加了一个用法示例,以防它对其他人也有帮助。
  • 你只需要像 assets.readAssetsFile("yourFile.json") 或 getAssets.readAssetsFile("courses.json") 一样调用它
【解决方案3】:
{ // json object node
    "formules": [ // json array formules
    { // json object 
      "formule": "Linear Motion", // string
      "url": "qp1"
    }

你在做什么

  Context context = null; // context is null 
    try {
        String jsonLocation = AssetJSONFile("formules.json", context);

所以改成

   try {
        String jsonLocation = AssetJSONFile("formules.json", CatList.this);

解析

我相信你从assets文件夹中得到了字符串。

try
{
String jsonLocation = AssetJSONFile("formules.json", context);
JSONObject jsonobject = new JSONObject(jsonLocation);
JSONArray jarray = (JSONArray) jsonobject.getJSONArray("formules");
for(int i=0;i<jarray.length();i++)
{
JSONObject jb =(JSONObject) jarray.get(i);
String formula = jb.getString("formule");
String url = jb.getString("url");
}
} catch (IOException e) {
        e.printStackTrace();
} catch (JSONException e) {
        e.printStackTrace();
}

【讨论】:

    【解决方案4】:

    从 Assets 文件夹中读取 JSON 文件并作为字符串对象返回的方法。

    public static String getAssetJsonData(Context context) {
                String json = null;
                try {
                    InputStream is = context.getAssets().open("myJson.json");
                    int size = is.available();
                    byte[] buffer = new byte[size];
                    is.read(buffer);
                    is.close();
                    json = new String(buffer, "UTF-8");
                } catch (IOException ex) {
                    ex.printStackTrace();
                    return null;
                }
    
                Log.e("data", json);
                return json;
    
            }
    

    现在解析您的活动中的数据:-

    String data = getAssetJsonData(getApplicationContext());
            Type type = new TypeToken<Your Data model>() {
            }.getType();
      <Your Data model> modelObject = new Gson().fromJson(data, type);
    

    【讨论】:

    • 嗨,您可能更喜欢添加导入库,因为它会警告您的代码有三个不同的地方。
    【解决方案5】:

    只是用一个对我有用的样本来总结@libing's answer

    val gson = Gson()
    val todoItem: TodoItem = gson.fromJson(this.assets.readAssetsFile("versus.json"), TodoItem::class.java)
    

    private fun AssetManager.readAssetsFile(fileName : String): String = open(fileName).bufferedReader().use{it.readText()}

    如果没有这个扩展功能,同样可以使用BufferedReaderInputStreamReader这样实现:

    val i: InputStream = this.assets.open("versus.json")
    val br = BufferedReader(InputStreamReader(i))
    val todoItem: TodoItem = gson.fromJson(br, TodoItem::class.java)
    

    【讨论】:

      【解决方案6】:

      使用OKIO

      implementation("com.squareup.okio:okio:3.0.0-alpha.4")
      

      使用 Java:

      public static String readJsonFromAssets(Context context, String filePath) {
              
                  try {
                      InputStream input = context.getAssets().open(filePath);
                      BufferedSource source = Okio.buffer(Okio.source(input));
                      return source.readByteString().string(Charset.forName("utf-8"));
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              
                  return null;
          }
      

      使用 Kotlin:

      fun readJsonFromAssets(context: Context, filePath: String): String? {
          try {
              val source = context.assets.open(filePath).source().buffer()
              return source.readByteString().string(Charset.forName("utf-8"))
                  
           } catch (e: IOException) {
                  e.printStackTrace()
           }
           return null
      }
      

      然后……

      String data = readJsonFromAssets(context, "json/some.json"); //here is my file inside the folder assets/json/some.json
      
      Type reviewType = new TypeToken<List<Object>>() {}.getType();
      
      if (data != null) {
          Object object = new Gson().fromJson(data, reviewType);
      }
      

      【讨论】:

      • 它可以工作,但有一个更正返回 source.readByteString(source.available()).string(Charset.forName("utf-8"))
      • 谢谢@MilanSheth
      【解决方案7】:

      如果您在 android 中使用 Kotlin,那么您可以创建 扩展函数
      扩展函数是在任何类之外定义的——但它们引用类名并且可以使用this。在我们的例子中,我们使用applicationContext
      所以在 Utility 类中你可以定义所有的扩展函数。


      Utility.kt

      fun Context.loadJSONFromAssets(fileName: String): String {
          return applicationContext.assets.open(fileName).bufferedReader().use { reader ->
              reader.readText()
          }
      }
      

      MainActivity.kt

      您可以像这样定义从断言中加载 JSON 数据的私有函数:

       lateinit var facilityModelList: ArrayList<FacilityModel>
       private fun bindJSONDataInFacilityList() {
          facilityModelList = ArrayList<FacilityModel>()
          val facilityJsonArray = JSONArray(loadJSONFromAsserts("NDoH_facility_list.json")) // Extension Function call here
          for (i in 0 until facilityJsonArray.length()){
              val facilityModel = FacilityModel()
              val facilityJSONObject = facilityJsonArray.getJSONObject(i)
              facilityModel.Facility = facilityJSONObject.getString("Facility")
              facilityModel.District = facilityJSONObject.getString("District")
              facilityModel.Province = facilityJSONObject.getString("Province")
              facilityModel.Subdistrict = facilityJSONObject.getString("Facility")
              facilityModel.code = facilityJSONObject.getInt("code")
              facilityModel.gps_latitude = facilityJSONObject.getDouble("gps_latitude")
              facilityModel.gps_longitude = facilityJSONObject.getDouble("gps_longitude")
      
              facilityModelList.add(facilityModel)
          }
      }
      

      你必须在你的ListView中传递facilityModelList


      FacilityModel.kt

      class FacilityModel: Serializable {
          var District: String = ""
          var Facility: String = ""
          var Province: String = ""
          var Subdistrict: String = ""
          var code: Int = 0
          var gps_latitude: Double= 0.0
          var gps_longitude: Double= 0.0
      }
      

      在我的例子中,JSON 响应以 JSONArray 开头

      [
        {
          "code": 875933,
          "Province": "Eastern Cape",
          "District": "Amathole DM",
          "Subdistrict": "Amahlathi LM",
          "Facility": "Amabele Clinic",
          "gps_latitude": -32.6634,
          "gps_longitude": 27.5239
        },
      
        {
          "code": 455242,
          "Province": "Eastern Cape",
          "District": "Amathole DM",
          "Subdistrict": "Amahlathi LM",
          "Facility": "Burnshill Clinic",
          "gps_latitude": -32.7686,
          "gps_longitude": 27.055
        }
      ]
      

      【讨论】:

        【解决方案8】:
        You have to write a function to read the Json File from your assests folder.
        
        public String loadJSONFile() {
            String json = null;
            try {
                InputStream inputStream = getAssets().open("yourfilename.json");
                int size = inputStream.available();
                byte[] byteArray = new byte[size];
                inputStream.read(byteArray);
                inputStream.close();
                json = new String(byteArray, "UTF-8");
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            return json;
        }
        

        【讨论】:

        • 此函数将 JSON 文件返回为字符串。之后将其解析为 JSONObject,例如:- JSONObject object = new JSONObject(loadJSONFile);现在根据您的 json 格式访问数据。
        【解决方案9】:

        源码如何从 Assets 文件夹中获取本地 Json

        https://drive.google.com/open?id=1NG1amTVWPNViim_caBr8eeB4zczTDK2p

            {
                "responseCode": "200",
                "responseMessage": "Recode Fetch Successfully!",
                "responseTime": "10:22",
                "employeesList": [
                    {
                        "empId": "1",
                        "empName": "Keshav",
                        "empFatherName": "Mr Ramesh Chand Gera",
                        "empSalary": "9654267338",
                        "empDesignation": "Sr. Java Developer",
                        "leaveBalance": "3",
                        "pfBalance": "60,000",
                        "pfAccountNo.": "12345678"
                    },
                    {
                        "empId": "2",
                        "empName": "Ram",
                        "empFatherName": "Mr Dasrath ji",
                        "empSalary": "9999999999",
                        "empDesignation": "Sr. Java Developer",
                        "leaveBalance": "3",
                        "pfBalance": "60,000",
                        "pfAccountNo.": "12345678"
                    },
                    {
                        "empId": "3",
                        "empName": "Manisha",
                        "empFatherName": "Mr Ramesh Chand Gera",
                        "empSalary": "8826420999",
                        "empDesignation": "BusinessMan",
                        "leaveBalance": "3",
                        "pfBalance": "60,000",
                        "pfAccountNo.": "12345678"
                    },
                    {
                        "empId": "4",
                        "empName": "Happy",
                        "empFatherName": "Mr Ramesh Chand Gera",
                        "empSalary": "9582401701",
                        "empDesignation": "Two Wheeler",
                        "leaveBalance": "3",
                        "pfBalance": "60,000",
                        "pfAccountNo.": "12345678"
                    },
                    {
                        "empId": "5",
                        "empName": "Ritu",
                        "empFatherName": "Mr Keshav Gera",
                        "empSalary": "8888888888",
                        "empDesignation": "Sararat Vibhag",
                        "leaveBalance": "3",
                        "pfBalance": "60,000",
                        "pfAccountNo.": "12345678"
                    }
                ]
            }
        
        
         @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_employee);
        
        
                emp_recycler_view = (RecyclerView) findViewById(R.id.emp_recycler_view);
        
                emp_recycler_view.setLayoutManager(new LinearLayoutManager(EmployeeActivity.this, 
                LinearLayoutManager.VERTICAL, false));
                emp_recycler_view.setItemAnimator(new DefaultItemAnimator());
        
                employeeAdapter = new EmployeeAdapter(EmployeeActivity.this , employeeModelArrayList);
        
                emp_recycler_view.setAdapter(employeeAdapter);
        
                getJsonFileFromLocally();
            }
        
        
        
            public String loadJSONFromAsset() {
                String json = null;
                try {
                    InputStream is = EmployeeActivity.this.getAssets().open("employees.json");       //TODO Json File  name from assets folder
                    int size = is.available();
                    byte[] buffer = new byte[size];
                    is.read(buffer);
                    is.close();
                    json = new String(buffer, "UTF-8");
                } catch (IOException ex) {
                    ex.printStackTrace();
                    return null;
                }
                return json;
            }
        
            private void getJsonFileFromLocally() {
                try {
        
                    JSONObject jsonObject = new JSONObject(loadJSONFromAsset());
                    String responseCode = jsonObject.getString("responseCode");
                    String responseMessage = jsonObject.getString("responseMessage");
                    String responseTime = jsonObject.getString("responseTime");
        
                    Log.e("keshav", "responseCode -->" + responseCode);
                    Log.e("keshav", "responseMessage -->" + responseMessage);
                    Log.e("keshav", "responseTime -->" + responseTime);
        
        
                    if(responseCode.equals("200")){
        
                    }else{
                        Toast.makeText(this, "No Receord Found ", Toast.LENGTH_SHORT).show();
                    }
        
                    JSONArray jsonArray = jsonObject.getJSONArray("employeesList");                  //TODO pass array object name
                    Log.e("keshav", "m_jArry -->" + jsonArray.length());
        
        
                    for (int i = 0; i < jsonArray.length(); i++)
                    {
                        EmployeeModel employeeModel = new EmployeeModel();
        
                        JSONObject jsonObjectEmployee = jsonArray.getJSONObject(i);
        
        
                        String empId = jsonObjectEmployee.getString("empId");
                        String empName = jsonObjectEmployee.getString("empName");
                        String empDesignation = jsonObjectEmployee.getString("empDesignation");
                        String empSalary = jsonObjectEmployee.getString("empSalary");
                        String empFatherName = jsonObjectEmployee.getString("empFatherName");
        
                        employeeModel.setEmpId(""+empId);
                        employeeModel.setEmpName(""+empName);
                        employeeModel.setEmpDesignation(""+empDesignation);
                        employeeModel.setEmpSalary(""+empSalary);
                        employeeModel.setEmpFatherNamer(""+empFatherName);
        
                        employeeModelArrayList.add(employeeModel);
        
                    }       // for
        
                    if(employeeModelArrayList!=null) {
                        employeeAdapter.dataChanged(employeeModelArrayList);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        

        【讨论】:

          猜你喜欢
          • 2017-12-23
          • 2017-11-02
          • 2020-11-27
          • 1970-01-01
          • 1970-01-01
          • 2018-11-01
          • 1970-01-01
          • 2017-09-21
          • 2012-09-05
          相关资源
          最近更新 更多