2

私は ImageView を持つアクティビティを持っています。それが空でクリックされた場合、インターネットから画像をロードして内部ストレージに保存する必要があります。したがって、アクティビティは次のようになります。

public class PlaceCreate extends Activity {
Context context;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.create);
  context = this;

  ImageView img = (ImageView) findViewById(R.id.imageView);
  img.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        EditText edit = (EditText)findViewById(R.id.editTextName);
        Download(edit.getText().toString());
    }
  });
}

private boolean Download(String Name)
{
  try
  {
    URL u = new URL("http://example.com/img.png");
    HttpURLConnection c = (HttpURLConnection)u.openConnection();
    c.setRequestMethod("GET");
    c.setDoOutput(true);
    c.connect();
    FileOutputStream f = context.openFileOutput(Name, Context.MODE_PRIVATE);
    InputStream in = c.getInputStream();
    byte[] buffer = new byte[1024];
    int len1 = 0;
    while((len1 = in.read(buffer)) > 0 )
    {
      f.write(buffer, 0, len1);
    }
    f.close();

    FileInputStream is = openFileInput(Name);
    Bitmap bitmap = BitmapFactory.decodeStream(is);
    is.close();
    ImageView img = (ImageView) findViewById(R.id.imageViewPlan);
    img.setImageBitmap(bitmap);
  }
  catch(IOException e)
  {
    return false;
  }
  return true;
}}

問題は、 の行で NullPointerException が発生することopenFileOutputです。null同様の質問をいくつか見つけましたが、すべての回答は、それが文脈の欠落であることを示唆しています。この場合はアクティビティであるため、明らかにコンテキスト ( this) があり、null ではありません。openFileOutput私は(this暗示的に)メンバー経由で電話をかけようとしましたcontext。どちらのアプローチも失敗します。v.getContext()また、追加のパラメーターとしてfromonClickに渡そうとしましDownloadたが、この値は null ではありませんでしたが、同じ例外も生成されました。(重要な場合は、要求されたファイルの名前は有効なファイル名です。たとえば、「abc」です。)

誰かがこれに光を当てることができますか?

スタックの例を次に示します。

04-22 00:45:10.659: W/dalvikvm(330): threadid=1: thread exiting with uncaught exception (group=0x40015560)
04-22 00:45:10.909: E/AndroidRuntime(330): FATAL EXCEPTION: main
04-22 00:45:10.909: E/AndroidRuntime(330): java.lang.NullPointerException
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.app.ContextImpl.openFileOutput(ContextImpl.java:420)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:158)
04-22 00:45:10.909: E/AndroidRuntime(330):  at com.example.scanner.PlaceCreate.Download(PlaceCreate.java:93)
04-22 00:45:10.909: E/AndroidRuntime(330):  at com.example.scanner.PlaceCreate.access$0(PlaceCreate.java:84)
04-22 00:45:10.909: E/AndroidRuntime(330):  at com.example.scanner.PlaceCreate$3.onClick(PlaceCreate.java:67)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.view.View.performClick(View.java:2485)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.view.View$PerformClick.run(View.java:9080)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.os.Handler.handleCallback(Handler.java:587)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.os.Handler.dispatchMessage(Handler.java:92)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.os.Looper.loop(Looper.java:123)
04-22 00:45:10.909: E/AndroidRuntime(330):  at android.app.ActivityThread.main(ActivityThread.java:3683)
04-22 00:45:10.909: E/AndroidRuntime(330):  at java.lang.reflect.Method.invokeNative(Native Method)
04-22 00:45:10.909: E/AndroidRuntime(330):  at java.lang.reflect.Method.invoke(Method.java:507)
04-22 00:45:10.909: E/AndroidRuntime(330):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-22 00:45:10.909: E/AndroidRuntime(330):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
04-22 00:45:10.909: E/AndroidRuntime(330):  at dalvik.system.NativeStart.main(Native Method)

そして、ここにいくつかの発見があります。ContextImplスタックによると、ファイル内でエラーが発生しており、parentこのメソッド内でローカル変数が null になっていることがわかります。コードは次のとおりです。

public FileOutputStream openFileOutput(String name, int mode)
  throws FileNotFoundException {
  final boolean append = (mode&MODE_APPEND) != 0;
  File f = makeFilename(getFilesDir(), name);
  try {
     FileOutputStream fos = new FileOutputStream(f, append);
     setFilePermissionsFromMode(f.getPath(), mode, 0);
     return fos;
  } catch (FileNotFoundException e) {
 }

 File parent = f.getParentFile();
 parent.mkdir();
 FileUtils.setPermissions(
     parent.getPath(),
     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
     -1, -1);
 FileOutputStream fos = new FileOutputStream(f, append);
 setFilePermissionsFromMode(f.getPath(), mode, 0);
 return fos;
}

f.getParentFile()ここで問題は、 への呼び出しが null を返さないことを確認するにはどうすればよいかということです。

4

5 に答える 5

2

問題は、openFileOutput の行で NullPointerException が発生することです。

の実装NullPointerException内部を取得しています。これが、例外名を提供するだけでなく、SO にスタック トレースを提供する必要がある理由です。回線上の例外は、回線によってトリガーされる例外とは異なります。特に.openFileOutput()NullPointerException

on の私の読書に基づいてopenFileOutput()、次のContextImplいずれか:

  • Namenullまたは
  • あなたは非常に奇妙なcontext、または
  • 実行している Android のバージョンには、現在の実装では表示されない他の問題が考えられます。openFileOutput()

あなたはの中にいて、それを必要としないので、私はcontext完全に削除することから始めます。Activity次に、いくつかのLogステートメントを挿入するか、ブレークポイントを設定して、何が何でNameあるかを確認します。

于 2012-04-21T20:17:40.810 に答える
1

これは、SDKの一部としてここにインストールされているAndroid2.3.3エミュレーターの機能であることが証明されています。Android 2.3.3で実際のデバイスを使用しても、問題は発生しません。また、Android 4.0.3エミュレーターを使用している場合、コードは正常に機能します。したがって、奇妙なことが起こった場合、別の環境でのテストが光を当てることができます。これが同様の問題解決において他の誰かを助けることができることを願っています。

于 2012-05-05T11:21:53.503 に答える
1

openFileOutput() のコードを読むと、他の回答やコメントで言及されていない f.getParentFile() が null を返す場合があることがわかります。

ラインで

File f = makeFilename(getFilesDir(), name);

dataDirが存在せず 、dataDir の作成に失敗した場合、 getFilesDir ()は null を返すことがありgetFilesDir()ます。これが発生した場合、ファイルが単なるファイル (「ファイル」など) ではなく、パス (「ディレクトリ/ファイル」など) であるf場合、ファイルは親のみを持つことになります。name

どのような状況で dataDir が欠落し、いつ作成できなくなるかはわかりませんが、何らかの理由で Android 2.3.3 エミュレーターで作成できない可能性は低いとは思えません。

于 2015-01-23T15:07:07.383 に答える
1

ICSを実行しているAsus TF101でも同じ問題がありました。つまり、エミュレーターではなく実際のデバイスです。この問題は、下層のフォルダーに対する Linux の書き込み権限に関連していることが判明したため、厄介でした。

android:sharedUserIdマニフェスト ファイルのタグで共有リソースを使用して遊んでいました。UID が変更されたため、アクティビティにはデータ ファイル ディレクトリへの書き込み権限がありません。

そのため、uid を変更する可能性のあるものはすべて、この問題を引き起こす可能性があります。

問題を解決するには:

  1. sharedUserIDマニフェストからタグを削除しました(オプションの可能性があります)。
  2. デバイスからアプリを手動でアンインストールしました。
  3. アプリを再インストールしました。

その後、完全に実行されました。

于 2012-10-04T08:34:53.077 に答える
0

この完全な例を参照してください

URL url = new URL (strURL);
input = url.openStream();
byte[] buffer = new byte[1500];
OutputStream output = new FileOutputStream ("/sdcard/abc.png");
int bytesRead = 0;
while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) .
{
 output.write(buffer, 0, bytesRead);
 }
于 2012-04-21T15:13:56.740 に答える