2014-06-06 25 views
0

我試圖使用谷歌的實用功能命名圖像文件。空指針異常使用類內的靜態「對象」

我把它們從相機應用程序的Util.java中提取出來。 許可證:

/* 
* Copyright (C) 2009 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

我正在寫單元測試他們有麻煩createJpegName

public class Util { 
    private static ImageFileNamer sImageFileNamer; 
    // don't instantiate this class, dummy 
    private Util() { 
    } 
    public static String createJpegName(long dateTaken) { 
    synchronized (sImageFileNamer) { 
     return sImageFileNamer.generateName(dateTaken); 
    } 
    } 
    private static class ImageFileNamer { 
    private SimpleDateFormat mFormat; 
    // The date (in milliseconds) used to generate the last name. 
    private long mLastDate; 
    // Number of names generated for the same second. 
    private int mSameSecondCount; 

    @SuppressWarnings("unused") 
    public ImageFileNamer(String format) { 
     mFormat = new SimpleDateFormat(format, Locale.US); 
    } 

    public String generateName(long dateTaken) { 
     Date date = new Date(dateTaken); 
     String result = mFormat.format(date); 
     // If the last name was generated for the same second, 
     // we append _1, _2, etc to the name. 
     if (dateTaken/1000 == mLastDate/1000) { 
     mSameSecondCount++; 
     result += "_" + mSameSecondCount; 
     } else { 
     mLastDate = dateTaken; 
     mSameSecondCount = 0; 
     } 
     return result; 
    } 
    } 

單元測試,爲後人:

public void testCreateJpegName() { 
// public static String createJpegName(long dateTaken) 
Calendar dateTime = Calendar.getInstance(); 
dateTime.set(1976, Calendar.SEPTEMBER, 20, 16, 20, 20); 
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020"); 
assertEquals(Util.createJpegName(dateTime.getTimeInMillis()),"19760920_162020_1"); 
} 

所以...我假設該sImageFileNamer沒有實例化,因爲我從來沒有創建一個Util對象,對嗎?

這是打算如何使用?我錯過了什麼?

其餘的util函數我可以在原地使用。

我每次嘗試訪問sImageFileNamer時都會得到一個NPE,在上面它發生在對syncronized()的調用中。

謝謝!

+0

你能否提供失敗的單元測試代碼? – ForguesR

回答

0

你必須確保sImageFileNamer在使用之前被初始化。因爲它是私人的,所以你只能從Util類裏面做。我建議你從一些方法做,或使用靜態初始化:

public class Util { 
    private static ImageFileNamer sImageFileNamer; 
    static { 
     sImageFileNamer = null; // replace null by whatever you want 
    } 
    // ... continue you class code 
} 

至於說here,靜態初始化自動和一次調用。我認爲這是你需要的。

+0

這個工程。並保持靜態。謝謝!我做了:'sImageFileNamer = new ImageFileNamer(「yyyyMMdd_HHmmss」);'因爲在這種情況下構造函數採用字符串日期格式ala simpleDateFormat – er0ck

1

您沒有使用​​塊之前之前初始化sImageFileNamer情況下做到這一點是:

public static String createJpegName(long dateTaken) { 
     sImageFileNamer= new ImageFileNamer(dateTaken); 
     synchronized (sImageFileNamer) { 
      return sImageFileNamer.generateName(dateTaken); 
     } 
    } 

或兩者類generateName方法是static,所以你可以不使用類名創建對象訪問。

+0

感謝您的回覆。這編譯和運行,但通過創建一個新的每一次createJpegName調用(或似乎)繞過sImageFileNamer的靜態性質。所以ImageFileNamer中的變量不會保留在調用中。 – er0ck