2016-03-08 7 views
-1

Я использую библиотеку залпа, чтобы подключиться к серверу и у меня есть класс транзакции и класс сервера с этим кодами:INT org.json.JSONArray.length() на объектную ссылку нулевой

Транс:

public class Trans extends Server { 
    public Object suggest(Context context) { 
     return connect("xxxxxxx", Request.Method.GET); 
    } 
} 

Сервер:

public Object connect(String url, int method) { 
    final Object[] object = {null}; 
    StringRequest postRequest; 
    postRequest = new StringRequest(method, url, 
      new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        object[0] = response; 
       } 
      }, 
      new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
       } 
      } 
    ) { 
     @Override 
     protected Map<String, String> getParams() throws AuthFailureError { 
      Map<String, String> params = new HashMap<String, String>(); 
      return params; 
     } 

     @Override 
     public String getBodyContentType() { 
      return "application/x-www-form-urlencoded; charset=UTF-8"; 
     } 
    }; 
    int socketTimeout = 20000; 
    RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 
      DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
      DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
    postRequest.setRetryPolicy(policy); 
    AppController.getInstance().addToRequestQueue(postRequest); 
    return object[0]; 
} 

Но когда я пытаюсь получить JSONArray с этим:

@Override 
protected void onResume() { 
    ArrayList<Suggests> arrayList = new ArrayList<>(); 
    JSONArray jsonArray = (JSONArray) trans.suggest(MainActivity.this); 
    for (int i = 0; i < jsonArray.length(); i++) { 
     try { 
      JSONObject item = (JSONObject) jsonArray.get(i); 
      Suggests suggests = new Suggests(); 
      suggests.title = item.getString("title"); 
      suggests.type = item.getString("type"); 
      arrayList.add(suggests); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 
    super.onResume(); 
} 

усилие, прилагаемое закрыто, и я эту ошибку в logcat:

java.lang.RuntimeException: Unable to resume activity {ir.aftabeshafa.shafadoc/ir.aftabeshafa.shafadoc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference 

В чем проблема и как я могу это исправить?

+0

Вы действительно получаете ответ от сервера? Потому что ваша функция 'trans.suggest' возвращает' null' – ChrisStillwell

+0

да, я уверен, и я тестирую ее с помощью Postman и печатал свой ответ в журнале. Все было прекрасно @ChrisStillwell –

+0

Ой, подождите, я вижу проблему ... вы возвращая 'object [0]' до того, как ваш запрос успеет закончить. Вместо того, чтобы возвращать свой объект, вы должны сделать обратный вызов в 'onResponse' и передать значение таким образом. – ChrisStillwell

ответ

0

Уходя предложения в комментариях,

Шаг 1 Определить интерфейс, который будет проходить по-результат вы хотите. <T> - это общий тип, поэтому вы можете возвращать любые нужные вам данные. Вы увидите, что на шаге 2.

public interface AsyncResponse<T> { 
    void onResponse(T response); 
} 

Шаг 2 Обновление сервера и классы Trans, чтобы принять это в качестве параметра

public class Server { 

    public void connect(String url, int method, final AsyncResponse<String> asyncResponse) { 
     StringRequest request = new StringRequest(method, url, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       if (asyncResponse != null) { 
        asyncResponse.onResponse(response); 
       } 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 
       Log.e("VolleyError", error.getMessage()); 
       Log.e("VolleyError", new String(error.networkResponse.data)); 
      } 
     }) { 
      @Override 
      protected Map<String, String> getParams() { 
       Map<String, String> params = new HashMap<String, String>(); 
       return params; 
      } 

      @Override 
      public String getBodyContentType() { 
       return "application/x-www-form-urlencoded; charset=UTF-8"; 
      } 
     }; 

     int socketTimeout = 20000; 
     RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 
       DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
       DefaultRetryPolicy.DEFAULT_BACKOFF_MULT); 
     request.setRetryPolicy(policy); 

     AppController.getInstance().addToRequestQueue(request); 
    } 
} 

Боковой вопрос: Вы действительно нуждаетесь в Context? Он не используется ...

public class Trans extends Server { 
    public void suggest(Context context, AsyncResponse<String> asyncResponse) { 
     connect("xxxxxxxx", Request.Method.GET, asyncResponse); 
    } 
} 

Шаг 3 Используйте свой метод, как так, чтобы получить результат в обратный вызов. Это было протестировано против URL-адреса http://jsonplaceholder.typicode.com/users, который возвращает JSONArray из 10 пользовательских объектов.

ArrayAdapter был добавлен для полного примера, так как он не появился ArrayList в вопросе был полезен ни для чего.

public class MainActivity extends AppCompatActivity { 

    private ArrayList<User> arrayList; 
    private Trans trans; 
    private ArrayAdapter<User> adapter; 
    private ListView listView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     trans = new Trans(); 
     arrayList = new ArrayList<User>(); 

     adapter = new ArrayAdapter<User>(MainActivity.this, android.R.layout.simple_list_item_1, arrayList); 
     listView = (ListView) findViewById(android.R.id.list); 
     listView.setAdapter(adapter); 

    } 

    @Override 
    protected void onResume() { 
     trans.suggest(MainActivity.this, new AsyncResponse<String>() { 
      @Override 
      public void onResponse(String response) { 
       arrayList.clear(); // prevent duplicate data 

       try { 
        // The URL that was tested returns a JSONArray 
        // Change to JSONObject, if necessary 
        JSONArray jsonArray = new JSONArray(response); 

        for (int i = 0; i < jsonArray.length(); i++) { 
         JSONObject item = (JSONObject) jsonArray.get(i); 
         User user = new User(); 
         user.username = item.getString("name"); 
         user.email = item.getString("email"); 
         arrayList.add(user); 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 

       // Notify since the arrayList has changed the adapter 
       adapter.notifyDataSetChanged(); 
      } 
     }); 

     super.onResume(); 
    } 
} 
+0

спасибо, что вы решили одну из самых больших проблем, которые у меня были. да, мне нужен контекст, потому что я получаю url и порт из файла конфигурации в активах. но еще один вопрос: возможно ли передать более одного запроса от разных функций Trans на сервер и получить ответ для каждого из них? –

+0

Вы можете принимать только один ответ за раз, но да, вы можете запускать многие методы «Trans.suggest» (или все, что вы хотите назвать). Просто передайте асинхронный ответ на залп и замените тело 'onResponse' тем, что вы хотите сделать –

+0

no я имею в виду от различных функций, таких как Trans.suggest и Trans.login в то же время? Является ли это возможным? –

Смежные вопросы