2015-05-26 3 views
2

Я пытаюсь создать приложение, которое вызывает веб-сервис через AsyncTask, однако приложение всегда вылетает после первой строки AsyncTask. Ниже мой код AsyncTask:AsyncTask падает после первой строки?

protected class AsyncGetItemByKey extends AsyncTask<String, JSONObject, ItemTable> { 

    String userName=null; 
    @Override 
    protected ItemTable doInBackground(String... params) { 
     itemTable = null; 
     //send the application context for preference retrieval 
     //RestAPI api = new RestAPI(getApplicationContext()); 
     RestAPI api = RestAPI.getInstance(getApplicationContext()); 
     try { 
      JSONObject jsonObj = api.GetHMMItemByKey(params[0],params[1]); 
      JSONParser parser = new JSONParser(); 
      itemTable = parser.parseItem(jsonObj); 

     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      Log.d("AsyncUserDetails", e.getMessage()); 
      System.out.println(e.toString()); 
     } 
     return itemTable; 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     //Toast.makeText(context, "Please Wait...", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    protected void onPostExecute(ItemTable itemTable) { 
     // TODO Auto-generated method stub 
    } 
} 

И это, как я называю AsyncTask при нажатии кнопки:

new AsyncGetItemByKey().execute(itemNumber, siteID); 

я поставил точку останова в моем AsyncTask и после первой строки имени пользователя = null, приложение аварийно завершает работу. Ниже также находится журнал:

05-26 16:16:34.600 3323-3323/com.binarystream.bssiapp E/AndroidRuntime﹕ FATAL EXCEPTION: main 
Process: com.binarystream.bssiapp, PID: 3323 
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference 
     at android.widget.Toast.<init>(Toast.java:101) 
     at android.widget.Toast.makeText(Toast.java:250) 
     at com.binarystream.bssiapp.SupplyReqMaintenanceActivity$1.onClick(SupplyReqMaintenanceActivity.java:91) 
     at android.view.View.performClick(View.java:4756) 
     at android.view.View$PerformClick.run(View.java:19749) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5221) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Я знаю, что что-то должно быть нулевым, но я не могу понять, что это такое. Я также попробовал itemTable = new ItemTable() вместо null, но это не помогло.

Любая помощь приветствуется! Спасибо!

+0

Если я правильно прочитал stacktrace, это из-за Toast, поэтому я бы предположил, что контекст имеет значение null. В вашем коде вы прокомментировали тост в методе OnPreExecute, так что вы используете тост где-нибудь еще? И где вы инициализируете контекст там? – mrtn

+0

Можете ли вы опубликовать RestAPI – Hades

+1

Является ли это внутренним классом в 'Деятельности'? Не могли бы вы просто использовать 'SupplyReqMaintenanceActivity.this', а не' getApplicationContext() '? – tachyonflux

ответ

4

В этом вопросе есть два вопроса.

Первый номер - это призывы к getApplicationContext() в AsyncTask. Причина, по которой это не работает, заключается в том, что когда вы вызываете getApplicationContext(), это действительно коротко для this.getApplicationContext(). Причина, по которой это будет работать в Activity, заключается в том, что он расширяет Context, который является классом, который содержит метод getApplicationContext(). С AsyncTask не распространяется Context, вы не можете использовать this как Context.

Вместо этого просто замените его на SupplyReqMaintenanceActivity.this, который вы можете использовать в качестве Context. Обратите внимание, что вы также можете позвонить SupplyReqMaintenanceActivity.this.getApplicationContext(), и это также будет актуально.

Просто убедитесь, что используете контекст контекста и контекста активности и знаете разницу между ними.

Второй вопрос заключается в том, что itemTable объявлен в SupplyReqMaintenanceActivity деятельности, но это также локальная переменная в методе onPostExecute(), как имя параметра, передаваемого в. Вы не можете иметь несколько переменных с тем же именем в том же объем.

Чтобы исправить это, просто переименуйте локальную переменную с областью действия в AsyncTask, чтобы она не противоречила переменной itemTable, объявленной в Activity.