说明:我分两个类,如下:
伪代码
public class A extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Do something
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Do something
}
public void onStart() {
super.onStart()
}
/* Etc more normal lifecycle callback methods.
*
*/
// Second Class enclosed in first class
public class B extends FragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
// Defined methods to be used by Class A.
}
现在是我的问题,当我尝试在类A中初始化类B时。就像
B b = new B();
的崩溃一样,我尝试在其上初始化类B(我尝试在各种Activity回调方法(例如onActivityCreated()
中)初始化类B。 ,OnCreateView()
等都不起作用,具体错误如下:空指针异常
在
android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:478)
& 在
android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
详细信息A类由MainActivity调用,该类又用两个选项卡填充了ActionBar。最后,这里是实际类B以及它调用的单独的异步类的代码。
public class rookWork extends FragmentActivity implements
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
LocationClient mLocationClient = new LocationClient(this, this, this);
public LocationClient setup() {
return mLocationClient;
}
@Override
public void onConnected(Bundle connectionHint) {
Toast.makeText(getApplicationContext(), "Connected!",
Toast.LENGTH_SHORT).show();
}
@Override
public void onDisconnected() {
Toast.makeText(getApplicationContext(), "Disconnected!",
Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the
* error has a resolution, try sending an Intent to start a Google
* Play services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult
.startResolutionForResult(
this,
LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
// If no resolution is available, display a dialog to the user
// with the error.
showErrorDialog(connectionResult.getErrorCode());
}
}
public void getAddress(View v) {
// In Gingerbread and later, use Geocoder.isPresent() to see if a
// geocoder is available.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
&& !Geocoder.isPresent()) {
// No geocoder is present. Issue an error message
Toast.makeText(getActivity(), R.string.no_geocoder_available,
Toast.LENGTH_LONG).show();
return;
}
if (servicesConnected()) {
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
// Turn the indefinite activity indicator on
mActivityIndicator.setVisibility(View.VISIBLE);
// Start the background task
GetAddressTask getAddressTask = new GetAddressTask(
getActivity());
getAddressTask.execute(currentLocation);
// (new
// GetAddressTask.GetAddressTask(this)).execute(currentLocation);
} else {
Toast.makeText(getActivity(), "servicesConnected() == false",
Toast.LENGTH_SHORT).show();
}
}
private boolean servicesConnected() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d(LocationUtils.APPTAG,
getString(R.string.play_services_available));
// Continue
return true;
// Google Play services was not available for some reason
} else {
// Display an error dialog
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(
resultCode, this, 0);
if (dialog != null) {
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(dialog);
errorFragment.show(getSupportFragmentManager(),
LocationUtils.APPTAG);
}
return false;
}
}
private void showErrorDialog(int errorCode) {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
errorCode, this,
LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment in which to show the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(getSupportFragmentManager(),
LocationUtils.APPTAG);
}
}
/**
* Define a DialogFragment to display the error dialog generated in
* showErrorDialog.
*/
@SuppressLint("ValidFragment")
public class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
/**
* Default constructor. Sets the dialog field to null
*/
@SuppressLint("ValidFragment")
public ErrorDialogFragment() {
super();
mDialog = null;
}
/**
* Set the dialog to display
*
* @param dialog
* An error dialog
*/
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
/*
* This method must return a Dialog to the DialogFragment.
*/
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
异步类:
/*
* Google Imports
*/
/*
* Android Imports
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import android.os.AsyncTask;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class GetAddressTask extends AsyncTask<Location, Void, String> {
Context mContext;
String addressText;
int test;
public GetAddressTask(Context context) {
super();
mContext = context;
}
@Override
protected String doInBackground(Location... params) {
/*
* Get a new geocoding service instance, set for localized addresses.
* This example uses android.location.Geocoder, but other geocoders that
* conform to address standards can also be used.
*/
Geocoder geocoder = new Geocoder(mContext, Locale.getDefault());
// Get the current location from the input parameter list
Location location = params[0];
// Create a list to contain the result address
List<Address> addresses = null;
// Try to get an address for the current location. Catch IO or network
// problems.
try {
/*
* Call the synchronous getFromLocation() method with the latitude
* and longitude of the current location. Return at most 1 address.
*/
addresses = geocoder.getFromLocation(location.getLatitude(),
location.getLongitude(), 1);
// Catch network or other I/O problems.
} catch (IOException exception1) {
// Log an error and return an error message
Log.e(LocationUtils.APPTAG,
mContext.getString(R.string.IO_Exception_getFromLocation));
// print the stack trace
exception1.printStackTrace();
// Return an error message
return (mContext.getString(R.string.IO_Exception_getFromLocation));
// Catch incorrect latitude or longitude values
} catch (IllegalArgumentException exception2) {
// Construct a message containing the invalid arguments
String errorString = mContext.getString(
R.string.illegal_argument_exception,
location.getLatitude(), location.getLongitude());
// Log the error and print the stack trace
Log.e(LocationUtils.APPTAG, errorString);
exception2.printStackTrace();
//
return errorString;
}
// If the reverse geocode returned an address
if (addresses != null && addresses.size() > 0) {
// Get the first address
Address address = addresses.get(0);
// Format the first line of address
String addressText = mContext.getString(
R.string.address_output_string,
// If there's a street address, add it
address.getMaxAddressLineIndex() > 0 ? address
.getAddressLine(0) : "",
// Locality is usually a city
address.getLocality(),
// The country of the address
address.getCountryName());
// Return the text
return addressText;
// If there aren't any addresses, post a message
} else {
return mContext.getString(R.string.no_address_found);
}
}
protected void onPostExecute(String result) {
/*
* Toast.makeText(mContext.getApplicationContext(), "Execution Done",
* Toast.LENGTH_SHORT).show();
*/
Toast.makeText(mContext.getApplicationContext(),
"Params Length: " + Integer.toString(test), Toast.LENGTH_SHORT)
.show();
}
}
最后一点
如果我注释掉B类(RookWork)的实例,一切运行正常。我以前可以使用Geocoder正常运行异步任务。但是,该设置不涉及将B类嵌入到A类中。
最佳答案
B类的举报(RookWork)
RookWork是Activity
。无法在Android中直接实例化活动。要创建新的活动,必须使用Intent。
如果In正确理解,则您需要一个Activity实例,因为某些与Google Play Services相关的方法(例如startResolutionForResult()
)需要一个。
最简单的解决方案可能是将所有这些代码(即接口的实现)移入片段本身,然后在需要活动时使用getActivity()
。它将返回片段当前附加到的活动。
例如:
public class A extends Fragment
implements GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener
{
...
@Override
public void onConnectionFailed(ConnectionResult connectionResult)
{
...
connectionResult.startResolutionForResult(getActivity(), LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);
...
}
...