运行时异常在后台执行

时间:2014-07-10 09:20:17

标签: android android-asynctask android-context

我无法从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

}

}

3 个答案:

答案 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();
}