I released an app today and I am getting some crash reports that indicate the following:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.app.Activity.findViewById(int)' on a null object reference
I have on Activity and a couple of Fragments. This error happens in one my Fragments where I have an AsyncTask:
private ProgressDialog dialog;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_dial, container, false);
dialog = new ProgressDialog(getActivity());
new CountryCodeTask().execute();
return view;
}
private class CountryCodeTask extends AsyncTask<Void, Void, ArrayList<String>>
{
@Override
protected void onPreExecute()
{
if (!dialog.isShowing()) {
dialog.show();
}
}
@Override
protected void onPostExecute(ArrayList<String> result)
{
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result != null) {
Spinner countryCodeSpinner = (Spinner) getActivity().findViewById(R.id.country_code_spinner);
countryCodeSpinner.setAdapter(new CountryCodeAdapter(getActivity(), result));
countryCodeSpinner.setSelection(countryCodeSpinnerValue);
countryCodes = result;
}
}
@Override
protected ArrayList<String> doInBackground(Void... params)
{
return MainActivity.apiService.getCountryCodes();
}
}
I am guessing this is not the best way to update the UI thread from a ASyncTask. This error happens when I use the back/home button and then restart the app (but not all the time). What am I doing wrong here?
The error happens on this line: Spinner countryCodeSpinner = (Spinner) getActivity().findViewById(R.id.country_code_spinner);
You're not doing anything wrong really - it's to be expected that when you navigate away from an Activity via back/home, the AsyncTask will no longer have a reference to the Activity. I would modify your code to handle this common scenario:
@Override
protected void onPostExecute(ArrayList<String> result)
{
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
Activity activity = getActivity();
if (activity != null) {
if (result != null) {
Spinner countryCodeSpinner = (Spinner) activity.findViewById(R.id.country_code_spinner);
countryCodeSpinner.setAdapter(new CountryCodeAdapter(activity, result));
countryCodeSpinner.setSelection(countryCodeSpinnerValue);
countryCodes = result;
} else {
cancelTaskAndShowDialog();
}
}
}
When your AsyncTask finishes, after you pressed back and left the activity, getActivity
returns null
.
You need to add a null
check in onPostExecute
final Activity activity = getActivity()
if (dialog =! null && dialog.isShowing()) {
dialog.dismiss();
}
if (activity != null) {
if (result != null) {
Spinner countryCodeSpinner = (Spinner) activity.findViewById(R.id.country_code_spinner);
countryCodeSpinner.setAdapter(new CountryCodeAdapter(activity, result));
countryCodeSpinner.setSelection(countryCodeSpinnerValue);
countryCodes = result;
}
}
Try this:
private ProgressDialog dialog;
private Spinner countryCodeSpinner;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_dial, container, false);
dialog = new ProgressDialog(getActivity());
new CountryCodeTask().execute();
countryCodeSpinner = (Spinner) view.findViewById(R.id.country_code_spinner);
return view;
}
private class CountryCodeTask extends AsyncTask<Void, Void, ArrayList<String>>
{
@Override
protected void onPreExecute()
{
if (!dialog.isShowing()) {
dialog.show();
}
}
@Override
protected void onPostExecute(ArrayList<String> result)
{
if (dialog.isShowing()) {
dialog.dismiss();
}
if (result != null) {
countryCodeSpinner.setAdapter(new CountryCodeAdapter(getActivity(), result));
countryCodeSpinner.setSelection(countryCodeSpinnerValue);
countryCodes = result;
}
}
@Override
protected ArrayList<String> doInBackground(Void... params)
{
return MainActivity.apiService.getCountryCodes();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.