空指针在调用位于片段内的Asynctask时发生异常

时间:2018-05-24 08:18:37

标签: android android-fragments android-context

我在调用Create报告时面临一个Null指针异常(它反过来调用它位于Activity内部的Asynctask“createReportTask”)但是应用程序崩溃在另一个片段的Asynsc任务(位于片段内)中给出了NPE,我试过了在构造函数中传递上下文等getContext(),getAcitivity()等但都是徒劳的。我附上日志和代码请帮助!!

日志:

    05-24 12:56:11.505 14632-14632/com.example.aiousecurityapplication E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.aiousecurityapplication, PID: 14632
    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
        at android.widget.Toast.<init>(Toast.java:121)
        at android.widget.Toast.makeText(Toast.java:291)
        at android.widget.Toast.makeText(Toast.java:281)
        at com.example.aiousecurityapplication.Activities.EventsReportFragment$MakeRequestTask.onPostExecute(EventsReportFragment.java:439)
        at com.example.aiousecurityapplication.Activities.EventsReportFragment$MakeRequestTask.onPostExecute(EventsReportFragment.java:377)
        at android.os.AsyncTask.finish(AsyncTask.java:727)
        at android.os.AsyncTask.-wrap1(Unknown Source:0)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:744)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:166)
        at android.app.ActivityThread.main(ActivityThread.java:7425)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

创建报告代码:

    public class CreateReport extends AppCompatActivity {
    public EditText eventDate;
    public EditText eventTime;
    EditText reporterName;
    EditText reporterCnic;
    int flag = 0;

    public static Calendar userCalendar;
    private String Lat, Long;
    private static final String[] BLOCK = new String[]{"Block 1", "Block 2", "Block 3", "Block 4", "Block 5"};
    private static final String[] sampleDesc = new String[]{"Aag Lagi ha", "Darwaza Khula h", "Tala Ni Laga", "Lights / Fan On hain"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_report);
        Button createReport = (Button) findViewById(R.id.createReport);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        final ActionBar ab = getSupportActionBar();
        ab.setTitle("Create Report");
        String myFormat1 = "yyyy-MM-dd";
        String myFormat2 = "HH:mm";
        SimpleDateFormat mainSdf1 = new SimpleDateFormat(myFormat1, Locale.US);
        SimpleDateFormat mainSdf2 = new SimpleDateFormat(myFormat2, Locale.US);


        Bundle bundle = getIntent().getExtras();

                 if (bundle != null) {
            Lat = bundle.getString("lat");
            Toast.makeText(getContext(), "Latitude" + Lat, Toast.LENGTH_LONG).show();
            Long = bundle.getString("Long");
        }
        createReport.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (eventDescription.getText().toString().length() < 3) {
                    eventDescription.setError("Minimum 5 Letters");
                    Toast.makeText(getApplicationContext(),
                            "Please some Description", Toast.LENGTH_SHORT)
                            .show();
                } else {
                    // creating new product in background thread

                    String blockname = blockName.getSelectedItem().toString().trim();
                    String eventEsc = eventEsclation.getSelectedItem().toString().trim();
                    String eventdesc = eventDescription.getText().toString().trim();
                    String cnic = reporterCnic.getText().toString().trim();
                    String userLat = Lat;
                    String userLong = Long;
                    String date = eventDate.getText().toString().trim();
                    String time = eventTime.getText().toString().trim();
                    new createReportTask().execute(blockname, eventEsc, eventdesc, cnic, userLat, userLong, date, time);
                }

            }
        });

    }

    public class createReportTask extends AsyncTask<String, String, JSONObject> {
        private JSONSenderReceiver jsonparser = new JSONSenderReceiver();
        ProgressDialog pDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d("Creating Report", "in Pre Execute");
            pDialog = new ProgressDialog(CreateReport.this);
            pDialog.setMessage("Creating Report");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        @Override
        protected void onPostExecute(JSONObject result) {
            super.onPostExecute(result);
            try {
                if (result == null) {
                pDialog.dismiss();
                    Toast.makeText(CreateReport.this, "No response from server.", Toast.LENGTH_SHORT).show();
                    return;
                }

                Log.d("Response from server: ", result.toString());
                int success = Integer.parseInt(result.getString("status"));
                String message = result.getString("message");

                if (success == 2) {

                    Toast.makeText(CreateReport.this, message, Toast.LENGTH_SHORT).show();
                }
            pDialog.dismiss();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        /**
         * Creating product
         */
        protected JSONObject doInBackground(String... args) {

            String blockName = args[0] != null ? args[0] : "";
            String eventEscalation = args[1];
            String eventDesc = args[2];
            String userCnic = args[3];
            String userLat = args[4];
            String userLong = args[5];
            String date = args[6];
            String time = args[7];

            if (blockName.trim().length() != 0 && eventEscalation.trim().length() != 0
                    && eventDesc.trim().length() != 0 && userCnic.trim().length() != 0 && userLat.trim().length() != 0
                    && userLong.trim().length() != 0 && date.trim().length() != 0 && time.trim().length() != 0) {
                //db field name in value side

                // Building Parameters

                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("page", "datasync"));
                params.add(new BasicNameValuePair("blockName", blockName));
                params.add(new BasicNameValuePair("eventEscalation", eventEscalation));
                params.add(new BasicNameValuePair("eventDesc", eventDesc));
                params.add(new BasicNameValuePair("userCnic", userCnic));
                params.add(new BasicNameValuePair("userLat", userLat));
                params.add(new BasicNameValuePair("userLong", userLong));
                params.add(new BasicNameValuePair("date", date));
                params.add(new BasicNameValuePair("time", time));

                // getting JSON Object
                // Note that create product url accepts POST method
                return jsonparser.makeHttpRequest(AppConfig.URL_MAIN, "POST", params);
            } else {
                return null;
            }
        }
    }
}

片段代码:

    public class EventsReportFragment extends Fragment {
    static final int REQUEST_AUTHORIZATION = 1001;
    private RecyclerView recyclerView;
    private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
    private boolean mAlreadyStartedService = false;
    private TextView mMsgView;
    View rootView;
    String latitude;
    String longitude;
    String myFormat1 = "yyyy-MM-dd";
    String myFormat2 = "HH:mm:ss";
    SimpleDateFormat mainSdf1 = new SimpleDateFormat(myFormat1, Locale.US);
    SimpleDateFormat mainSdf2 = new SimpleDateFormat(myFormat2, Locale.US);

    public EventsReportFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        LocalBroadcastManager.getInstance(getContext()).registerReceiver(
                new BroadcastReceiver() {
                    @Override
                    public void onReceive(Context context, Intent intent) {
                        latitude = intent.getStringExtra(LocationMonitoringService.EXTRA_LATITUDE);
                        longitude = intent.getStringExtra(LocationMonitoringService.EXTRA_LONGITUDE);
                        new MakeRequestTask().execute(AppSettings.getUserCnic(), latitude, longitude,
                                mainSdf1.format(Calendar.getInstance().getTime()),
                                mainSdf2.format(Calendar.getInstance().getTime()));

                        if (latitude != null && longitude != null) {
                            mMsgView.setText("msg_location_service_started" + "\n Latitude : " + latitude + "\n Longitude: " + longitude);
                        }
                    }
                }, new IntentFilter(LocationMonitoringService.ACTION_LOCATION_BROADCAST)
        );
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_events_list, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
        mMsgView = (TextView) rootView.findViewById (R.id.msgView);
        FloatingActionButton fab = (FloatingActionButton) rootView.findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getActivity(), CreateReport.class);
                intent.putExtra("lat", latitude);
                intent.putExtra("long", longitude);
                startActivity(intent);
            }
        });
        return rootView;

    }

    @Override
    public void onResume() {
        super.onResume();

        startStep1();
    }


    /**
     * Step 1: Check Google Play services
     */
    private void startStep1() {

        //Check whether this user has installed Google play service which is being used by Location updates.
        if (isGooglePlayServicesAvailable()) {

            //Passing null to indicate that it is executing for the first time.
            startStep2(null);

        } else {
            Toast.makeText(getContext(), "no_google_playservice_available", Toast.LENGTH_LONG).show();
        }
    }


    /**
     * Step 2: Check & Prompt Internet connection
     */
    private Boolean startStep2(DialogInterface dialog) {
        ConnectivityManager connectivityManager
                = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

        if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
            promptInternetConnect();
            return false;
        }


        if (dialog != null) {
            dialog.dismiss();
        }


        if (checkPermissions()) { //Yes permissions are granted by the user. Go to the next step.
            startStep3();
        } else {  //No user has not granted the permissions yet. Request now.
            requestPermissions();
        }
        return true;
    }

    /**
     * Show A Dialog with button to refresh the internet state.
     */
    private void promptInternetConnect() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle("title_alert_no_intenet");
        builder.setMessage("msg_alert_no_internet");

        String positiveText = "Refresh Button";
        builder.setPositiveButton(positiveText,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {


                        //Block the Application Execution until user grants the permissions
                        if (startStep2(dialog)) {

                            //Now make sure about location permission.
                            if (checkPermissions()) {

                                //Step 2: Start the Location Monitor Service
                                //Everything is there to start the service.
                                startStep3();
                            } else if (!checkPermissions()) {
                                requestPermissions();
                            }

                        }
                    }
                });

        AlertDialog dialog = builder.create();
        dialog.show();
    }

    /**
     * Step 3: Start the Location Monitor Service
     */
    private void startStep3() {

        //And it will be keep running until you close the entire application from task manager.
        //This method will executed only once.

        if (!mAlreadyStartedService && mMsgView != null) {

            mMsgView.setText("Location_service_started");

            //Start location sharing service to app server.........
            Intent intent = new Intent(getContext(), LocationMonitoringService.class);
            getActivity().startService(intent);

            mAlreadyStartedService = true;
            //Ends................................................
        }
    }

    /**
     * Return the availability of GooglePlayServices
     */
    public boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
        int status = googleApiAvailability.isGooglePlayServicesAvailable(getContext());
        if (status != ConnectionResult.SUCCESS) {
            if (googleApiAvailability.isUserResolvableError(status)) {
                googleApiAvailability.getErrorDialog(getActivity(), status, 2404).show();
            }
            return false;
        }
        return true;
    }


    /**
     * Return the current state of the permissions needed.
     */
    private boolean checkPermissions() {
        int permissionState1 = ActivityCompat.checkSelfPermission(getContext(),
                android.Manifest.permission.ACCESS_FINE_LOCATION);

        int permissionState2 = ActivityCompat.checkSelfPermission(getContext(),
                Manifest.permission.ACCESS_COARSE_LOCATION);

        return permissionState1 == PackageManager.PERMISSION_GRANTED && permissionState2 == PackageManager.PERMISSION_GRANTED;

    }

    /**
     * Start permissions requests.
     */
    private void requestPermissions() {

        boolean shouldProvideRationale =
                ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                        android.Manifest.permission.ACCESS_FINE_LOCATION);

        boolean shouldProvideRationale2 =
                ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
                        Manifest.permission.ACCESS_COARSE_LOCATION);


        // Provide an additional rationale to the img_user. This would happen if the img_user denied the
        // request previously, but didn't check the "Don't ask again" checkbox.
        if (shouldProvideRationale || shouldProvideRationale2) {
            Log.i(TAG, "Displaying permission rationale to provide additional context.");
            showSnackbar(R.string.permission_rationale,
                    android.R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // Request permission
                            ActivityCompat.requestPermissions(getActivity(),
                                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                                    REQUEST_PERMISSIONS_REQUEST_CODE);
                        }
                    });
        } else {
            Log.i(TAG, "Requesting permission");
            // Request permission. It's possible this can be auto answered if device policy
            // sets the permission in a given state or the img_user denied the permission
            // previously and checked "Never ask again".
            ActivityCompat.requestPermissions(getActivity(),
                    new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                    REQUEST_PERMISSIONS_REQUEST_CODE);
        }
    }


    /**
     * Shows a {@link Snackbar}.
     *
     * @param mainTextStringId The id for the string resource for the Snackbar text.
     * @param actionStringId   The text of the action item.
     * @param listener         The listener associated with the Snackbar action.
     */
    private void showSnackbar(final int mainTextStringId, final int actionStringId,
                              View.OnClickListener listener) {
        Snackbar.make(
                rootView.findViewById(android.R.id.content),
                getString(mainTextStringId),
                Snackbar.LENGTH_INDEFINITE)
                .setAction(getString(actionStringId), listener).show();
    }

    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        Log.i(TAG, "onRequestPermissionResult");
        if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
            if (grantResults.length <= 0) {
                // If img_user interaction was interrupted, the permission request is cancelled and you
                // receive empty arrays.
                Log.i(TAG, "User interaction was cancelled.");
            } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                Log.i(TAG, "Permission granted, updates requested, starting location updates");
                startStep3();

            } else {

                showSnackbar(R.string.permission_denied_explanation,
                        R.string.settings, new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                // Build intent that displays the App settings screen.
                                Intent intent = new Intent();
                                intent.setAction(
                                        Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package",
                                        BuildConfig.APPLICATION_ID, null);
                                intent.setData(uri);
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                startActivity(intent);
                            }
                        });
            }
        }
    }


    @Override
    public void onDestroy() {


        //Stop location sharing service to app server.........

        getActivity().stopService(new Intent(getActivity(), LocationMonitoringService.class));
        mAlreadyStartedService = false;
        //Ends................................................


        super.onDestroy();
    }


    public class MakeRequestTask extends AsyncTask<String, String, JSONObject> {

        private Exception mLastError = null;
        private JSONSenderReceiver jsonparser = new JSONSenderReceiver();

        public MakeRequestTask() {

        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }


        @Override
        protected JSONObject doInBackground(String... args) {
            try {
                String cnic = args[0];
                String userLat = args[1];
                String userLong = args[2];
                String date = args[3];
                String time = args[4];

                List<NameValuePair> params = new ArrayList<NameValuePair>();

                if (cnic.trim().length() != 0 && userLat.trim().length() != 0
                        && userLong.trim().length() != 0 && date.trim().length() != 0 && time.trim().length() != 0) {

                    params.add(new BasicNameValuePair("page", "locationUpdate"));
                    params.add(new BasicNameValuePair("cnic", cnic));
                    params.add(new BasicNameValuePair("userLat", userLat));
                    params.add(new BasicNameValuePair("userLong", userLong));
                    params.add(new BasicNameValuePair("date", date));
                    params.add(new BasicNameValuePair("time", time));
                }
                return jsonparser.makeHttpRequest(AppConfig.URL_MAIN, "POST", params);

            } catch (Exception e) {
                e.printStackTrace();
                mLastError = e;
                cancel(true);
                return null;
            }
        }

        @Override
        protected void onPostExecute(JSONObject result) {
            super.onPostExecute(result);
            try {
                if (result == null) {
                    Toast.makeText(getContext(), "No response from server.", Toast.LENGTH_SHORT).show();
                    return;
                }

                Log.d("Response from server: ", result.toString());
                int success = Integer.parseInt(result.getString("status"));
                String message = result.getString("message");

                if (success == 1) {

                    Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();

                } else if (success == 2){

                    Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onCancelled() {

        }

    }

}``

4 个答案:

答案 0 :(得分:0)

在onPostExecute中,在执行任何工作之前检查活动是否正在运行。 因为如果活动不再运行,可能会调用onPostExecute

答案 1 :(得分:0)

试试这个

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
 rootView = inflater.inflate(R.layout.fragment_events_list, container, false);

 LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    latitude = intent.getStringExtra(LocationMonitoringService.EXTRA_LATITUDE);
                    longitude = intent.getStringExtra(LocationMonitoringService.EXTRA_LONGITUDE);
                    new MakeRequestTask().execute(AppSettings.getUserCnic(), latitude, longitude,
                            mainSdf1.format(Calendar.getInstance().getTime()),
                            mainSdf2.format(Calendar.getInstance().getTime()));

                    if (latitude != null && longitude != null) {
                        mMsgView.setText("msg_location_service_started" + "\n Latitude : " + latitude + "\n Longitude: " + longitude);
                    }
                }
            }, new IntentFilter(LocationMonitoringService.ACTION_LOCATION_BROADCAST)
    );
   //your remaining code here
}

答案 2 :(得分:0)

使用以下行:

String message = result.optString("message");
// it will returns the empty string ("") if the key you specify doesn't exist

而不是使用

String message = result.getString("message");
// it will throws exception if the key you specify doesn't exist

答案 3 :(得分:0)

getContext()替换为片段中的getActivity()

例如替换    Toast.makeText(getContext(), "no_google_playservice_available", Toast.LENGTH_LONG).show();

 `Toast.makeText(getActivity(), "no_google_playservice_available", Toast.LENGTH_LONG).show();` 

LocalBroadcastManager.getInstance(getContext()).registerReceiver(         

LocalBroadcastManager.getInstance(getActivity()).registerReceiver(    

依此类推。