我无法从asynctask
中的活动中获取结果。 Eclipse在doInBackground()上显示运行时异常。当我更改构造函数时,它给出了空指针异常。
请帮助我得到我的结果。
public class DataCtrl extends AsyncTask<Void, Void, String>{
int position;
Context context;
String strValue;
String data = null;
public AsyncResponse delegate=null;
android.support.v4.app.FragmentTransaction myft;
double lat;
double longi;
LocationCtrl gps;
public DataCtrl(int position, android.support.v4.app.FragmentTransaction ft, Context con){
this.position = position;
this.myft = ft;
context = con;
gps = new LocationCtrl();
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
}
@Override
protected String doInBackground(Void... params) {
// TODO Auto-generated method stub
double lat = 0;
gps.turnGPSOn();
gps.getMyCurrentLocation();
Location loc = gps.getLastKnownLocation(context);
if (loc != null) {
lat = loc.getLatitude();
longi = loc.getLongitude();
}
Log.i("lat", Double.toString(lat));
if(data == null) {
data = GET("http://twyst.in/api/v2/data/28/77");
return data;
}
else {
return data;
}
}
public static String GET(String url){
InputStream inputStream = null;
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
inputStream = httpResponse.getEntity().getContent();
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return result;
}
// convert inputstream to String
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
Bundle bundle = new Bundle();
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result) {
setData(result, position);
}
public void setData(String result, int pos) {
Fragment fragment = null;
Bundle bundle = new Bundle();
bundle.putString("data", result);
switch (pos) {
case 0:
Fragment forme= new ForMeActivity();
forme.setArguments(bundle);
myft.replace(R.id.mainContent, forme);
myft.commit();
break;
case 1:
Fragment my= new MyTwystActivity();
my.setArguments(bundle);
myft.replace(R.id.mainContent, my);
myft.commit();
break;
case 2:
Fragment near= new NearByActivity();
near.setArguments(bundle);
myft.replace(R.id.mainContent, near);
myft.commit();
break;
default:
break;
}
}
}
public class LocationCtrl extends Activity {
private boolean gps_enabled=false;
private boolean network_enabled=false;
Location location;
Double MyLat, MyLong;
Context context;
TextView textView2,textView3;
Button button1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Method to turn on GPS **/
public void turnGPSOn(){
try
{
@SuppressWarnings("deprecation")
String provider = Settings.Secure.getString(getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(!provider.contains("gps")){ //if gps is disabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
}
}
catch (Exception e) {
}
}
// Method to turn off the GPS
public void turnGPSOff(){
@SuppressWarnings("deprecation")
String provider = Settings.Secure.getString(getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if(provider.contains("gps")) { //if gps is enabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
turnGPSOff();
}
void getMyCurrentLocation() {
LocationManager locManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
LocationListener locListener = new MyLocationListener();
try{gps_enabled=locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);}
catch(Exception ex){}
try{network_enabled=locManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}
catch(Exception ex){}
//don't start listeners if no provider is enabled
//if(!gps_enabled && !network_enabled)
//return false;
if(gps_enabled){
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locListener);
}
if(gps_enabled){
location=locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if(network_enabled && location==null){
locManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locListener);
}
if(network_enabled && location==null) {
location=locManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
if (location != null) {
MyLat = location.getLatitude();
MyLong = location.getLongitude();
}
else {
Location loc= getLastKnownLocation(this);
if (loc != null) {
MyLat = loc.getLatitude();
MyLong = loc.getLongitude();
}
}
locManager.removeUpdates(locListener); // removes the periodic updates from location listener
try
{
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
addresses = geocoder.getFromLocation(MyLat, MyLong, 1);
}
catch (Exception e)
{
e.printStackTrace();
}
textView2.setText(""+MyLat);
textView3.setText(""+MyLong);
}
public Location getLastKnownLocation(Context context) {
// TODO Auto-generated method stub
Location location = null;
LocationManager locationmanager = (LocationManager)context.getSystemService("location");
List<?> list = locationmanager.getAllProviders();
boolean i = false;
Iterator<?> iterator = list.iterator();
do
{
if(!iterator.hasNext())
break;
String s = (String)iterator.next();
if (i != false && !locationmanager.isProviderEnabled(s))
continue;
Location location1 = locationmanager.getLastKnownLocation(s);
if(location1 == null)
continue;
if(location != null)
{
float f = location.getAccuracy();
float f1 = location1.getAccuracy();
if(f >= f1)
{
long l = location1.getTime();
long l1 = location.getTime();
if(l - l1 <= 600000L)
continue;
}
}
location = location1;
i = locationmanager.isProviderEnabled(s);
} while(true);
return location;
}
}
logcat的:
07-10 09:04:23.760: E/AndroidRuntime(3163): FATAL EXCEPTION: AsyncTask #1
07-10 09:04:23.760: E/AndroidRuntime(3163): java.lang.RuntimeException: An error occured while executing doInBackground()
07-10 09:04:23.760: E/AndroidRuntime(3163): at android.os.AsyncTask$3.done(AsyncTask.java:200)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.lang.Thread.run(Thread.java:1019)
07-10 09:04:23.760: E/AndroidRuntime(3163): Caused by: java.lang.IllegalStateException: System services not available to Activities before onCreate()
07-10 09:04:23.760: E/AndroidRuntime(3163): at android.app.Activity.getSystemService(Activity.java:3536)
07-10 09:04:23.760: E/AndroidRuntime(3163): at com.twyst.android.LocationCtrl.getMyCurrentLocation(LocationCtrl.java:93)
07-10 09:04:23.760: E/AndroidRuntime(3163): at com.twyst.android.DataCtrl.doInBackground(DataCtrl.java:72)
07-10 09:04:23.760: E/AndroidRuntime(3163): at com.twyst.android.DataCtrl.doInBackground(DataCtrl.java:1)
07-10 09:04:23.760: E/AndroidRuntime(3163): at android.os.AsyncTask$2.call(AsyncTask.java:185)
07-10 09:04:23.760: E/AndroidRuntime(3163): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
07-10 09:04:23.760: E/AndroidRuntime(3163): ... 4 more
MainActivity.java
public class MainActivity extends ActionBarActivity implements OnItemClickListener, AsyncResponse {
private DrawerLayout drawerLayout;
private ListView listView;
private String[] menus;
private ActionBarDrawerToggle drawerListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// dataCtrl.delegate = this;
menus = getResources().getStringArray(R.array.menus);
drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
drawerListener = new ActionBarDrawerToggle(this, drawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open,
R.string.drawer_close) {
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
};
listView = (ListView) findViewById(R.id.drawerList);
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, menus));
listView.setOnItemClickListener(this);
drawerLayout.setDrawerListener(drawerListener);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
updateDisplay(0);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
drawerListener.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(drawerListener.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onPostCreate(savedInstanceState);
drawerListener.syncState();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(this, menus[position], Toast.LENGTH_LONG).show();
updateDisplay(position);
}
public void updateDisplay(int position) {
selectItem(position);
android.support.v4.app.FragmentManager myfm = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction myft = myfm.beginTransaction();
new DataCtrl(position, myft, this).execute();
}
public void selectItem(int position) {
listView.setItemChecked(position, true);
setTitle(menus[position]);
//selectItem(pos);
drawerLayout.closeDrawer(listView);
}
public void setTitle (String title) {
getSupportActionBar().setTitle(title);
}
@Override
public void getData(String output, int position) {
// TODO Auto-generated method stub
}
}
答案 0 :(得分:1)
问题是您甚至在活动中的onCreate()
方法之前尝试访问某些系统级服务。
请从您的Activity中删除所有构造函数,并将构造函数内的处理移动到onCreate()
方法。
编辑1:
因此,您正在使用活动的构造函数来访问活动方法,例如turnGPSOn()
等,但这些方法需要系统服务来获取位置。因此,当您创建活动类的对象时,您会收到异常,因为当您的活动尚未 创建 但活动构造函数中的代码尝试调用时系统相关服务。
解决方案:您应该将每个GPS相关任务移动到您的活动中。例如。应在您的活动的onCreate()方法内调用GPS方法。所以基本上,你的代码中有很多不正确的东西。我建议你用下面的例子重写。
简单示例:
public class MainActivity extends ActionBarActivity implements LocationListener {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* Turn on GPS Here. Basically everything that need to do before your
* network connection should go here.
*/
// Call your async task
new GPSTask().execute();
}
private class GPSTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
/** Make network request here */
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
/**
* Update Fragments here.
* To be able to access variables from the MainActivity.
* Declare them as instance variables;
*/
tv.setText("onPostExecute");
}
}
}
答案 1 :(得分:0)
在AsyncTask中,要获得Activity
,您需要从该活动的context
获取该活动,而不是创建该活动的构造函数。
由于活动构造函数中没有Context
,因此它仅在Activity.onCreate()
方法及更高版本中可用。
所以在DataCtrl
构造函数更改
gps = new LocationCtrl();
到
gps = (Activity)context;
答案 2 :(得分:0)
我会做这样的事情(仅用于查找您的位置)
在您的主要活动中:
public LocationClient mLocationClient;
ProgressDialog pd;
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_layout_file, container, false);
mLocationClient = new LocationClient(getActivity(), this, this);
rootView.findViewById(R.id.locButton).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
pd = ProgressDialog.show(getActivity(), "",
"Finding you!!!", false);
getAddress(v);
}
});
getAddress方法:
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()) {
// Turn the indefinite activity indicator on
// Start the background task
GetAddressTask getAddressTask = new GetAddressTask(getActivity(),
mLocationClient, pd);
getAddressTask.delegate = this;
getAddressTask.execute(currentLocation);
} else {
Toast.makeText(getActivity(), "servicesConnected() == false",
Toast.LENGTH_SHORT).show();
}
}
异步类GetAddressTask:
public AsyncResponse delegate = null;
ProgressDialog pd;
protected String doInBackground() {
// Show user progress
pd.show();
// Get the current location
Location currentLocation = mLocationClient.getLastLocation();
Lat = currentLocation.getLatitude();
Lng = currentLocation.getLongitude();
// Now do whatever else!
}
protected void onPostExecute(String result) {
delegate.processFinished(result);
// Do other stuff
// Kill Progress Dialog;
pd.hide();
}