【问题标题】:FATAL EXCEPTION: Thread-128 java.lang.NullPointerException致命异常:线程 128 java.lang.NullPointerException
【发布时间】:2016-03-28 06:50:56
【问题描述】:

今天我构建了一个新的应用程序来添加联系人,但是我在 log cat 中有这样的错误:

threadid=11:线程以未捕获的异常退出(组=0xa4ca6b20)

致命异常:线程 128

进程:kr.co.composer.callrecord,PID:5275 java.lang.NullPointerException

在 android.content.ContextWrapper.getContentResolver(ContextWrapper.java:99)

在 kr.co.composer.callrecord.page.AddContactActivity.insertContact(AddContactActivity.java:116)

在 kr.co.composer.callrecord.callbroadcast.CallBroadcast$1.run(CallBroadcast.java:110)

在 java.lang.Thread.run(Thread.java:841)

我认为课堂上有问题insertContact

ContentResolver contentResolver = this.getContentResolver();

查看更多代码,这个类是从AppCompatActivity扩展而来的:

public boolean insertContact(String firstName, String mobileNumber, String addressCall, String timeStart, String currentDate) {
    ContentResolver contentResolver = this.getContentResolver();
    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.RawContacts.CONTENT_URI)
            .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
            .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
            .build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, firstName + " " + timeStart + " " + currentDate).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
            .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, mobileNumber)
            .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build());
    ops.add(ContentProviderOperation
            .newInsert(ContactsContract.Data.CONTENT_URI)
            .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID,
                    0)
            .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE )
            .withValue(ContactsContract.CommonDataKinds.StructuredPostal.STREET, addressCall).build());
    try {
        contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
    } catch (Exception e) {
        return false;
    }
    return true;
}

毕竟,在CallBroadcast 中,我已经用所有参数调用了这个类(我插入的值不为空)。

InputStream answerInputStream = connection.getInputStream();
final String answer = getTextFromInputStream(answerInputStream);

if(answer!="") {
    String[] contactInfo = answer.split(":::::");

    contact.insertContact(contactInfo[0], contactInfo[1], contactInfo[2], contactInfo[3], contactInfo[4]);
}

answer 的值为:

Alisan:::::".$text.":::::10p.m at Yusski street:::::25/03/2015:::::28/03/2015

class CallBroadcast extends BroadcastReceiver 我调用insertContact 方法。您可以在下面看到更多代码:

public class CallBroadcast extends BroadcastReceiver {
    public void sendToServer(final String text){
        contact = new AddContactActivity();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                    String textparam = "text1=" + URLEncoder.encode(text, "UTF-8");

                    URL scripturl = new URL(scripturlstring);
                    HttpURLConnection connection = (HttpURLConnection) scripturl.openConnection();
                    connection.setDoOutput(true);
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    connection.setFixedLengthStreamingMode(textparam.getBytes().length);
                    OutputStreamWriter contentWriter = new OutputStreamWriter(connection.getOutputStream());
                    contentWriter.write(textparam);
                    contentWriter.flush();
                    contentWriter.close();

                    InputStream answerInputStream = connection.getInputStream();
                    final String answer = getTextFromInputStream(answerInputStream);

                    if(answer!="") {
                        String[] contactInfo = answer.split(":::::");

                        contact.insertContact(contactInfo[0], contactInfo[1], contactInfo[2], contactInfo[3], contactInfo[4]);
                    }
                    answerInputStream.close();
                    connection.disconnect();


                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }
}

@Override
public void onReceive(final Context context, final Intent intent) {
    callState = 0;
    callInfoPreferenceManager = CallInfoPreferenceManager.getInstance();
    configPreferenceManager = ConfigPreferenceManager.getInstance();

    TelephonyManager telManager = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
    if (configPreferenceManager.getAutoRecord()) {
        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
            String textToServer = callInfoPreferenceManager.getPhoneNumber();
            sendToServer(textToServer.toString());
            Log.i("Gọi đến đã gửi->server:", textToServer.toString());
            callInfoPreferenceManager.setPhoneNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
            callInfoPreferenceManager.setMyPhone(number);
            callInfoPreferenceManager.setSending(String.valueOf(true));
        }
    }
    telManager.listen(new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            callDAO = new CallDAO(context);
            if (configPreferenceManager.getAutoRecord()) {
                if (state != pState) {
                    if (state == TelephonyManager.CALL_STATE_OFFHOOK && callInfoPreferenceManager.getCallState()) {
                        uri = Uri.withAppendedPath(
                                ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                                Uri.encode(callInfoPreferenceManager.getPhoneNumber()));
                        projection = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
                                , ContactsContract.Contacts.PHOTO_ID
                        };

                        // Query the filter URI
                        Cursor cursor = context.getContentResolver().query(uri,
                                projection, null, null, null);
                        if (cursor != null) {
                            if (cursor.moveToFirst()) {
                                callInfoPreferenceManager.setName(cursor.getString(cursor.getColumnIndex
                                        (ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)));
                                int id = cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.PHOTO_ID));
                                if (id != 0) {
                                    callInfoPreferenceManager.setPhotoId(id);
                                } else {
                                    callInfoPreferenceManager.setPhotoId(1);
                                }
                            } else {
                                callInfoPreferenceManager.setPhotoId(1);
                                callInfoPreferenceManager.setName("Số lạ");
                            }
                        }
                        cursor.close();

                        callInfoPreferenceManager.setCallState(CALLING);
                        callInfoPreferenceManager.setStartDate(DateFormat.format(
                                CallFormatter.START_DATE_FORMAT,
                                System.currentTimeMillis()).toString());

                        callInfoPreferenceManager.setStartTime(System
                                .currentTimeMillis());
                        try {
                            Thread.sleep(1000);                 //1000 milliseconds is one second.
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                        sIntent = new Intent(context.getApplicationContext(),
                                CallRecordService.class);
                        context.startService(sIntent);

                    } else if (state == TelephonyManager.CALL_STATE_RINGING && callInfoPreferenceManager.getCallState()) {
                        callInfoPreferenceManager.setPhoneNumber(incomingNumber);
                        String textToServer = callInfoPreferenceManager.getPhoneNumber();
                        sendToServer(textToServer.toString());
                        callInfoPreferenceManager.setSending(String.valueOf(false));

                    } else if (state == TelephonyManager.CALL_STATE_IDLE && callInfoPreferenceManager.getCallState() == CALLING) {
                        long endTime = System.currentTimeMillis();
                        long startTime = callInfoPreferenceManager.getStartTime();
                        long callTime = endTime - startTime;
                        String totalTime = new SimpleDateFormat(
                                CallFormatter.TIME_FORMAT).format(new Date(
                                callTime - 32400000));
                        callDAO.insert(callInfoPreferenceManager.getName(),
                                callInfoPreferenceManager.getPhoneNumber(),
                                callInfoPreferenceManager.getStartDate(),
                                totalTime,
                                callInfoPreferenceManager.getSending(),
                                callInfoPreferenceManager.getPhotoId(),
                                callInfoPreferenceManager.getStartDate()
                                        + configPreferenceManager.getPathFormat());
                        callDAO.close();

                        sIntent = new Intent(context.getApplicationContext(),
                                CallRecordService.class);
                        context.stopService(sIntent);

                        callInfoPreferenceManager.setCallState(IDLE);
                        try {
                            Thread.sleep(1000);                 //1000 milliseconds is one second.
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                    } else if (state == TelephonyManager.CALL_STATE_RINGING &&
                            callInfoPreferenceManager.getCallState() == CALLING) {
                        callState = REFUSE;
                    } else if (state == TelephonyManager.CALL_STATE_OFFHOOK && callInfoPreferenceManager.getCallState()
                            == CALLING) {
                        callState = ACCEPT;
                    } else if (state == TelephonyManager.CALL_STATE_IDLE && callState == REFUSE) {
                        callInfoPreferenceManager.setCallState(IDLE);
                    }
                    pState = state;
                }
            }
        }
    }, PhoneStateListener.LISTEN_CALL_STATE);
}//onReceive

我检查了你的答案,但是在编辑我的代码时,一个类也调用insertContact,我尝试添加onCreate(Context context, Bundle savedInstanceState),但不能使用带有参数Context context 的传递。这段代码位于:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);

        addContactBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (insertContact(name, number, address, timeStart, timeCurrrentDate)) {
                }
            }
        }
    }
}

【问题讨论】:

  • @RohitArya 我更新了所有错误日志。
  • 你在哪里定义了insertContact方法?在activityfragment?
  • 另外,你从哪里调用insertContact 方法?来自哪个activity 回调的含义?
  • @RohitArya 我更新了一个调用insertContact 方法的类。
  • 你从哪里调用sendToServer方法?这是必需的,因为我仍然找不到让context 调用getContentResolver() 方法的来源。

标签: java android multithreading nullpointerexception


【解决方案1】:

getContentResolver() 是类android.content.Context 的方法,所以它肯定需要一个Context 的实例(如ActivityService)。 这就是崩溃的原因。

你在打电话

ContentResolver contentResolver = this.getContentResolver();

这里this 应该是Context 的子类的实例。如果您已经从 activity 调用它,请确保在 activityonCreate 方法之后调用它,因为到那时 activity 类没有 context

编辑 1:

由于您使用的是Broadcast Receiver,您应该传递context 在此处收到:

onReceive (Context context, Intent intent){}

像这样public void sendToServer( Context context, final String text) 更改sentToServer 方法的签名并通过contextonReceive 调用。

@Override
public void onReceive (Context context, Intent intent){
     sendToServer(context, "some text")
}

同样,更改insertContact方法public boolean insertContact(Context context, String firstName, String mobileNumber, String addressCall, String timeStart, String currentDate)的签名

然后像这样得到ContentResolver

ContentResolver contentResolver = context.getContentResolver();

希望对你有所帮助!

【讨论】:

  • 感谢您的回答。我更新了我的问题。在其他类中,我也使用调用insertContactonCreate 事件。我尝试添加 Context context 但不工作。
  • 属于哪一类?你也能更新一下吗?顺便说一句,如果这个解决方案解决了你的问题,你可以投票并接受它吗?
  • 在这个类中我初始化:private static Context mContext; 并在onCreate 事件中添加新行mContext = getApplicationContext();。这工作。
  • 它会起作用,但它不是一个好主意。如果它是一个活动,请使用activity's context not application context。做这样的事情mContext = MyActivity.this;
  • 是的,您可以使用它。因为AppCompactActivity 最终会扩展Context
猜你喜欢
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 2016-11-30
  • 2013-08-11
相关资源
最近更新 更多