【问题标题】:FileOutputStream issue with writing JSON from URL to internal storage将 JSON 从 URL 写入内部存储的 FileOutputStream 问题
【发布时间】:2014-04-29 14:08:43
【问题描述】:

我正在将 JSON 写入要访问的文件,以从我的应用程序中消除尽可能多的网络访问/延迟。我以前没有处理过将文件写入内存的问题,并且从 Google 的文档中获取了大部分读/写代码,但我仍然遇到问题。

目前,我在这一行遇到空指针异常:

FileOutputStream fOut = openFileOutput("runesInfo.json", Context.MODE_PRIVATE)

这让我相信该文件从未创建过,或者我将其初始化错误,但我不确定如何创建。

完整的代码部分:

public class GetRunes extends AsyncTask<String, String, String> {

        boolean runesCached = false;

        protected String doInBackground(String[] runeId) {
            String url = "https://prod.api.pvp.net/api/lol/static-data/" + region + "/v1.2/rune?api_key=" + api_key;
            JSONParser jsonParser = new JSONParser();
            JSONObject runeInfo = jsonParser.getJSONFromUrl(url);
            String jsonString = runeInfo.toString();
            String readJson = null;
            Context context = GetStaticData.this;

            if(!runesCached) {
                Log.d("Cache", "Caching File");

                try {
                    File file = new File(context.getFilesDir(), "runesInfo.json");
                    FileOutputStream fOut = openFileOutput("runesInfo.json", Context.MODE_PRIVATE);
                    fOut.write(jsonString.getBytes());
                    fOut.close();
                    Log.d("Cache", "Cache Complete");
                    runesCached = true;

                } catch (Exception e){
                    e.printStackTrace();
                }

            }

            String name = null;
            try {
                FileInputStream fis = openFileInput("runesInfo.json");
                InputStreamReader isr = new InputStreamReader(fis);

                fis.read(readJson.getBytes());
                JSONObject storedJson = new JSONObject(readJson);
                Log.d("Stored JSON", "" + storedJson);
                JSONObject idJson = storedJson.getJSONObject("data");
                JSONObject single = idJson.getJSONObject(runeId[0]);


                try {
                    name = single.getString("name");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (StreamCorruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return name;
        }
    }

Logcat:

04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats D/Cache﹕ Caching File
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ java.lang.NullPointerException
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at android.content.ContextWrapper.getFilesDir(ContextWrapper.java)
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.GetStaticData$GetRunes.doInBackground(GetSt
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.GetStaticData$GetRunes.doInBackground(GetSt
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java)
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java)
04-29 09:53:58.199  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java)
04-29 09:53:58.209  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
04-29 09:53:58.209  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
04-29 09:53:58.209  11273-11732/edu.appdesign.leaguestats W/System.err﹕ at java.lang.Thread.run(Thread.java)
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ java.util.concurrent.ExecutionException: java.lang.NullPointerException
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.FutureTask.report(FutureTask.java)
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.FutureTask.get(FutureTask.java)
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask.get(AsyncTask.java)
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.GetStaticData.getRuneInfo(GetStaticData.jav
04-29 09:53:58.209  11273-11732/edu.appdesign.leaguestats W/dalvikvm﹕ threadid=20: thread exiting with uncaught exception (group=0x41650e18)
04-29 09:53:58.209  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.RunesActivity$GetRunes.onPostExecute(RunesA
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.RunesActivity$GetRunes.onPostExecute(RunesA
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask.finish(AsyncTask.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask.access$600(AsyncTask.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.Looper.loop(Looper.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)

04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java)
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit
04-29 09:53:58.219  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:133)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ Caused by: java.lang.NullPointerException
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.content.ContextWrapper.openFileInput(ContextWrapper.java)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.GetStaticData$GetRunes.doInBackground(GetSt
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at edu.appdesign.leaguestats.GetStaticData$GetRunes.doInBackground(GetSt
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java)
04-29 09:53:58.229  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.
04-29 09:53:58.239  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor
04-29 09:53:58.239  11273-11273/edu.appdesign.leaguestats W/System.err﹕ at java.lang.Thread.run(Thread.java)

【问题讨论】:

  • 请分享logcat。
  • @ManishMulimani 添加了相关的 logcat 部分
  • 我认为,可能是因为上下文错误。 GetRunes 是内部类吗? openFileOutput 是 Context 的一种方法(很可能是 Activity)。它在您的代码中可能为 null,因为 doInBackground 在单独的线程中执行。因此,尝试添加“上下文”。到它并检查它是否不为空。顺便说一句,尽量避免在静态变量中保存上下文。
  • @Olsavage GetRunes 是 GetStaticData 类中的一个类,由我的活动 RunesActivity 调用。这是否意味着我应该使用 RunesActivity 作为上下文?澄清一下,有 2 个文件,GetStaticData,其中包含 GetRunes 和 RunesActivity。
  • 您应该使用非空上下文的 openFileOutput。它可能是 RunesActivity,如果它已经创建但尚未完成。 GetStaticData 扩展了什么?

标签: android json file-io


【解决方案1】:

我推荐使用安卓Service。我认为,它将最适合您的需求。只需将您的代码移动到服务,摆脱静态上下文,在 onStartCommand 方法执行 AsyncTask 并调用 startService,当您需要保存 JSON。

【讨论】:

    【解决方案2】:
    File file = new File(context.getFilesDir(), "runesInfo.json");
    FileOutputStream fOut = openFileOutput("runesInfo.json", Context.MODE_PRIVATE);
    

    您创建了一个文件实例,但从不在流中使用它。

    FileOutputStream fOut = new FileOutputStream(new File(context.getFilesDir(), "runesInfo.json"));
    

    应该做的工作。

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      相关资源
      最近更新 更多