如何将资产文件夹中的本地 JSON 文件解析为 ListView?
Posted
技术标签:
【中文标题】如何将资产文件夹中的本地 JSON 文件解析为 ListView?【英文标题】:How can I parse a local JSON file from assets folder into a 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_
android:layout_
android:measureWithLargestChild="false"
android:orientation="vertical"
tools:context=".CatList" >
<RelativeLayout
android:layout_
android:layout_
android:background="@drawable/titlebar" >
<TextView
android:id="@+id/Title1"
android:layout_
android:layout_
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_
android:layout_ >
</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"
]
我尝试了很多东西,甚至删除了整个项目重新创建一个:(
【问题讨论】:
以上代码的输出是什么?看来您将字符串解析为 json 对象.. @WildSushi 看看我的回答。 @GrlsHu 我实际上正在测试该代码:D 几乎与Reading a json file in Android重复。 @Sushii 看看我的回答。- ***.com/a/51095837/3560104 【参考方案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().useit.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().useit.readText()
如果没有这个扩展功能,同样可以使用BufferedReader
和InputStreamReader
这样实现:
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();
【讨论】:
以上是关于如何将资产文件夹中的本地 JSON 文件解析为 ListView?的主要内容,如果未能解决你的问题,请参考以下文章
如何将资产文件夹中的 JSON 数据加载到 Recyclerview