8

Tôi muốn hỏi tại sao chúng ta có được chú thích này:Android:. GetContext() getContentResolver() đôi khi được NullPointerException

Phương pháp gọi getContext.getContentResolver() có thể sản xuất NullPointerException

Tại sao nó ở đó và không có trong các phần khác của chương trình Fragment/Activity? Cách tiếp cận đó đã được sử dụng trong hướng dẫn của Google - đây là liên kết cho mã ContentProvider https://github.com/udacity/Sunshine-Version-2/blob/sunshine_master/app/src/main/java/com/example/android/sunshine/app/data/WeatherProvider.java ngay cả khi bạn tạo một ứng dụng chỉ với một hoạt động trống và đưa phương thức đó vào một ContentProvider mới được tạo ở đó.

Chúng ta có nên sử dụng getContext().getContentResolver().notifyChange(uri, null); bên ngoài Trình ContentProvider lấy uri được chuyển đi và sau đó sau khi cập nhật/chèn/xóa xong thì notifyChange? hoặc có lẽ chúng ta có thể sửa nó bằng cách nào đó?

+0

Nó chỉ là một cảnh báo đơn giản nếu IDE của bạn rằng 'getContext()' có thể trở lại 'null' và 'getContext(). getContentResolver()' sau đó có thể gây ra 'NullPointerException'. – Tom

Trả lời

8

Nếu bạn nhìn vào nguồn gốc của ContentProvider (chỉ giữ SHIFT và bấm vào tên lớp trong Android Studio) thì bạn sẽ thấy rằng việc thực hiện đang giữ một đối tượng kiểu Context là mContext.

Giải pháp của bạn chỉ giống nhau, có nghĩa là nếu mContext của ContentProvider là null, tham chiếu của bạn cũng sẽ là rỗng. Vì vậy, không cần thiết cho việc này.

Để giúp bạn hiểu, đây chỉ là cảnh báo về IDE của bạn nếu bạn tự tạo dựng cấu trúc như vậy. Nhưng trong trường hợp này sẽ luôn có ngữ cảnh, bởi vì ContentProvider được tạo ra bởi hệ thống của bạn. Để tránh lỗi này trong IDE của bạn chỉ cần viết @SuppressWarnings ("ConstantConditions") trên định nghĩa lớp học của bạn như:

... 
@SuppressWarnings("ConstantConditions") 
public class NoteProvider extends ContentProvider { 
... 
+0

Bỏ qua các cảnh báo đó trong cả lớp là ý tưởng tồi, ít nhất bạn nên sử dụng một cái gì đó như '// noinspection ConstantConditions' trước dòng mã đó - điều đó sẽ tắt cảnh báo đó chỉ cho dòng mã tiếp theo – mmrmartin

2

Viết getApplicationContext().getContentResolver() Hy vọng điều này sẽ hiệu quả.

+1

Tôi chỉ có thể sử dụng 'getContext(). GetApplicationContext(). GetContentResolver(); 'và' getContext(). getApplicationContext() 'đang tạo ra cùng một kết quả. –

7

Nếu bạn có thể đảm bảo rằng getContext() không bao giờ có thể là null thì bạn có thể dễ dàng bỏ qua cảnh báo này. Tôi nghĩ rằng cảnh báo thậm chí biến mất của bạn chỉ cần kiểm tra cho null:

if (getContext() != null) { 
    getContext().getContentResolver(); 
} 

Bạn chỉ cần phải ghi nhớ mã sẽ không được thực hiện nếu getContext()rỗng.

Cheers

chỉnh sửa: Hãy cẩn thận với những câu trả lời @Shivani Gupta cho bạn, bởi vì bạn có thể nhận được những bối cảnh khác nhau. Xem: Difference between getContext() , getApplicationContext() , getBaseContext() and "this"

0

Bất cứ khi nào bạn cố gắng sử dụng thành viên hoặc phương pháp của đối tượng, bạn có thể có ngoại lệ thời gian chạy nếu đối tượng có thành viên/phương pháp bạn cố gắng sử dụng là rỗng. Giả sử bạn muốn sử dụng một thành viên/phương thức của một đối tượng, obj. Nếu bạn sử dụng nó như thế này:

if (obj != null) { 
    //use members/methods of obj 
} 

thì bạn đã ngăn chặn sự cố. Tuy nhiên, bạn có thể muốn xử lý nó như một ngoại lệ, như thế này:

try { 
    //use members/methods of obj 
} catch (NullPointerException npe) { 
    //handle the NullPointerException 
} 
0

Ok có vẻ như tôi cố định nó bản thân mình bằng cách tuyên bố Context trên beggining của lớp.

public class NoteProvider extends ContentProvider { 
    Context context; 

sau đó khởi tạo nó trong onCreate()

@Override 
    public boolean onCreate() { 
     mSQLiteOpenHelper = new NoteDbHelper(getContext()); 
     context = getContext(); 

     return true; 
    } 

Tôi nghĩ rằng chắc chắn rằng tôi luôn luôn có bối cảnh khi tôi sử dụng context.getContentResolver() notifyChange (uri, null). hoặc retCursor.setNotificationUri (context.getContentResolver(), uri); trong phương thức chèn/cập nhật/xóa/truy vấn- retCursor được trả về con trỏ bằng các phương pháp đã đề cập.

Tôi đã chạy ứng dụng trên điện thoại của mình và chưa gặp sự cố nếu tôi có thể sẽ chỉnh sửa cho bài đăng này.

EDIT:

Nó không tạo sự khác biệt sau khi tất cả - explanationin câu trả lời bằng @Mate, cảm ơn bạn vì điều đó tôi nghĩ mình hiểu rồi:]

+1

giải pháp của bạn chỉ là lừa IDE, getContext cung cấp cho bạn một tham chiếu đến mContext của ContentProvider, nếu điều này là null ngữ cảnh của bạn cũng sẽ là rỗng. Nhưng đừng lo lắng, nó không thể được null, xem câu trả lời của tôi. – Mate

0

Theo ContentProvider getContext() docs:

Lấy bối cảnh nhà cung cấp này đang chạy trong. Chỉ có một khi onCreate() đã được gọi - điều này sẽ trả về null trong hàm tạo.

Vì vậy, các phương pháp getContext() không trả lại null trong insert(), update() hoặc delete(), vì onCreate() sẽ được gọi trước khi các cuộc gọi.

Vì vậy, nó là OK để vô hiệu hóa cảnh báo rằng cho dòng rằng nếu bạn sử dụng nó trong trường hợp như vậy ...

//noinspection ConstantConditions 
getContext().getContentResolver().notifyChange(uri, null); 
Các vấn đề liên quan