2012-04-21 53 views
2

我有一個ImageView的,如果它是,空的和點擊時,應該從因特網加載圖像,並保存到內部存儲器中的活動。因此,活動如下:的NullPointerException在openFileOutput在活動

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),並且它不爲空。我嘗試致電openFileOutput(暗示爲this),並通過context成員。兩種方法都失敗。此外,我試圖從onClick通過v.getContext()Download作爲附加參數,該值是不是空的,但所產生的相同的異常爲好。 (如果是重要的,請求的文件的名稱是一個有效的文件名,例如「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,爲什麼它的工作原理不時?

+0

當你說...名稱是一個有效的文件名,例如「abc」,是你嘗試過的實際文件名? – Squonk 2012-04-21 13:56:46

+1

請提供完整的堆棧跟蹤。 – CommonsWare 2012-04-21 14:58:17

+0

@MisterSquonk:是的,我也嘗試過'abc'。這個名字有什麼問題? – Stan 2012-04-21 18:57:19

回答

1

這被證明是Android 2.3.3仿真器的一個特性,作爲SDK的一部分安裝在這裏。如果我在Android 2.3.3上使用真實設備,則不會發生此問題。如果我使用Android 4.0.3模擬器,代碼也可以正常工作。所以,如果發生一些奇怪的事情,在另一個環境中的測試可以發現一些亮點。我希望這可以幫助其他人解決類似的問題。

+0

是否報告此錯誤? – d34th4ck3r 2012-07-30 22:45:01

+0

@ d34th4ck3r,不,不清楚哪個產品受到影響和/或哪些環境設置導致問題。另外,我想首先從其他人那裏得到一些問題的確認。 – Stan 2012-08-02 21:04:57

+0

你可以在我的確認。 – d34th4ck3r 2012-08-03 21:48:51

0

看到this完整的例子

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); 
} 
+0

不幸的是,我不需要外部存儲(如SD卡),我需要內部存儲。在這個例子中,我看到,單個文件名(沒有路徑)是可以的。 – Stan 2012-04-21 18:55:52

2

的問題是,我得到的NullPointerException與openFileOutput行了。

你得到一個NullPointerException實施openFileOutput()。這就是爲什麼您需要爲SO提供堆棧跟蹤,而不僅僅是提供異常名稱。上異常一個線比異常不同通過觸發的線,特別是與NullPointerException

基於我對ContextImplopenFileOutput()閱讀,或者:

  • Namenull,或
  • 你有一個非常奇怪的context,或
  • 沒有對版本的一些其他可能出現的問題Android版正在運行,是不是在目前執行的openFileOutput()
可見

我會刪去context完全啓動,因爲你是一個Activity內,並不需要它。然後,輸入一些Log語句或設置斷點以查看Name是什麼。

+0

您是否看到堆棧和新發現問題的新版本? ContextImpl中帶有'f.getParentFile()'的行生成'null'。 – Stan 2012-04-21 20:37:27

+0

@Stan:當'f.getParentFile()'返回'null'時,'f'包含了什麼? – CommonsWare 2012-04-21 20:39:28

+0

˚F\t文件(ID = 830007877600)\t \t absolutePath \t 「/ A」(ID = 830007877752)\t \t路徑\t 「A」(ID = 830007877784)母公司空,這意味着我選擇的名稱'了'這個時間。 – Stan 2012-04-21 20:46:59

1

我在運行ICS的華碩TF101上也遇到了同樣的問題 - 即真實的設備而不是仿真器。這是令人煩惱的,因爲事實證明問題與底層文件夾的Linux寫入權限有關。

我一直在玩清單文件中使用共享資源和android:sharedUserId標籤。由於UID已更改,該活動不再具有數據文件目錄中的寫入權限。

所以任何可能改變uid的東西都可能會導致這個問題。

爲了解決這個問題I:

  1. 刪除從清單中的sharedUserID標籤(可能可選);
  2. 手動從我的設備上卸載應用程序。
  3. 重新安裝了應用程序。

然後它完美地運行。

1

通過閱讀openFileOutput()的代碼,我可以看到一個情況,其中f.getParentFile()可能返回null,這裏沒有提到任何其他答案或評論。

在行

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

getFilesDir()可以返回null如果dataDir不存在,如果getFilesDir()無法創建DATADIR。如果發生這種情況,文件f只有在name是路徑(如「目錄/文件」)而不僅僅是文件(如「文件」)時纔會有父項。

我不知道dataDir會在什麼情況下丟失,什麼時候不可能創建它,但不會因爲某些原因而無法在Android 2.3.3 Emulator中創建它。

相關問題