2015-03-01 5 views
0

Мне нужно разработать приложение для Android, которое выполняет HTTP-запрос GET на сервер, который отвечает строкой JSON.Возвращение результата запроса HTTP в действие

Поскольку мне нужно сделать этот запрос больше времени в приложении, я создал класс только для выполнения этой задачи, используя AsyncTask.

Проблема заключается в том, что я не могу вернуть жало JSON из AsyncTask в действие и прочитать некоторые вопросы, которые я понял, что AsynkTask не является решением, поэтому я попытался выполнить запрос используя службу Android, но у меня есть NetworkOnMainThreadException.

Как создать новый поток для запуска службы и отправить результат в действие?

+0

Если я понял ваш вопрос правильно, я предполагаю, что вы могли бы создать функцию обратного вызова для вызова всякий раз, когда AsyncTask заканчивается, а затем использовать в качестве введите обратный вызов данные, которые вы хотите обработать в своей деятельности? – ArchiFloyd

+0

Да, в качестве ввода AsyncTask я добавляю URL-адрес веб-службы, и я использую строку вывода для управления различными параметрами в приложении. – Marco

ответ

0

Мне нравится использовать groundy для службы команды

public class LoginCommand extends GroundyTask{ 
private static final String ARG_PASSWORD = "arg_password"; 
private static final String ARG_USER = "arg_username"; 

@Override 
protected TaskResult doInBackground() { 
    String userName = getStringArg(ARG_USER); 
    String password = getStringArg(ARG_PASSWORD); 
    //do something 
    return succeeded(); 
} 

public static void start(Context context, BaseLoginCommandCallback callback, String login, String password) { 
    Groundy.create(LoginCommand.class) 
      .arg(ARG_USER, login) 
      .arg(ARG_PASSWORD, password) 
      .callback(callback) 
      .queueUsing(context); 
} 

public static abstract class BaseLoginCommandCallback{ 

    @OnSuccess(LoginCommand.class) 
    public void handleSuccess(){ 
     onLoginSuccess(); 
    } 

    @OnFailure(LoginCommand.class) 
    public void handleFailure(){ 
     onLoginError(); 
    } 

    protected abstract void onLoginSuccess(); 

    protected abstract void onLoginError(); 
} 
}  

или использовать retrofit + gson ─ Вы можете использовать groundy/AsyncTask/услуги + переоснащение или использовать асинхронный запрос ДООСНАСТКУ

модель:

public class SignRequest { 
private String login; 
private String password; 

public SignRequest(String login, String password) { 
    this.login = login; 
    this.password = password; 
} 

public SignRequest() { 
} 

public String getLogin() { 
    return login; 
} 

public void setLogin(String login) { 
    this.login = login; 
} 

public String getPassword() { 
    return password; 
} 

public void setPassword(String password) { 
    this.password = password; 
     } 
}  




public class SignResponse implements Parcelable { 
private long id; 
private String login; 
private String message; 
@SerializedName("auth_token") 
private String authToken; 

public long getId() { 
    return id; 
} 

public void setId(long id) { 
    this.id = id; 
} 

public String getLogin() { 
    return login; 
} 

public void setLogin(String login) { 
    this.login = login; 
} 

public String getMessage() { 
    return message; 
} 

public void setMessage(String message) { 
    this.message = message; 
} 

public String getAuthToken() { 
    return authToken; 
} 

public void setAuthToken(String authToken) { 
    this.authToken = authToken; 
} 




public SignResponse() { 
} 

public SignResponse(Parcel in) { 
    this.id = in.readLong(); 
    this.login = in.readString(); 
    this.message = in.readString(); 
    this.authToken = in.readString(); 

} 

@Override 
public int describeContents() { 
    return 0; 
} 

@Override 
public void writeToParcel(Parcel out, int flags) { 
    out.writeLong(id); 
    out.writeString(login); 
    out.writeString(message); 
    out.writeString(authToken); 
} 
} 

API:

public interface Api { 
public static final String URL = "http://xxxxxx/api/v1"; 
static final String AUTH_SIGNIN = "/auth/signin"; 
static final String AUTH_SIGNUP = "/auth/signup"; 

static final String QUERY_AUTH_TOKEN = "auth_token"; 

@POST(AUTH_SIGNIN) 
void sign(@Body SignRequest request, Callback<SignResponse> callback); 
@POST(AUTH_SIGNIN) 
SignResponsesign(@Body SignRequest request); 
@POST(AUTH_SIGNUP) 
void signup(@Body SignUpRequest request, Callback<SignUpResponse> callback); 

} 

ASYNCHRONOUS:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);   
    setContentView(R.layout.activity_auth); 
    RestAdapter restAdapter = new RestAdapter.Builder() 
      .setEndpoint(Api.URL) 
      .build(); 
    Api api = restAdapter.create(Api.class); 
    SignRequest request= new SignRequest(); 
    request.setLogin(login); 
    request.setPassword(password); 
    api.sign(request, new Callback<SignResponse>() { 
     @Override 
     public void success(SignResponse signResponse, Response response) { 
      Log.d("api", "login: " + signResponse.getLogin()); 
     ....... 
     } 

     @Override 
     public void failure(RetrofitError error) { 
      ..... 
    }); 

} 

SYNCHRONOUS (для Exemple AsyncTask):

...... 
@Override 
protected Void doInBackground(SignRequest... params) { 
    SignRequest request = params[0]; 
    RestAdapter restAdapter = new RestAdapter.Builder() 
      .setEndpoint(Api.URL) 
      .build(); 
    Api api = restAdapter.create(Api.class); 
    SignResponse response = api.sign(request); 

    return null; 
} 

..... 
0

Как я уже сказал @ZygoteInit, вы должны использовать AsyncTask. Также вы можете применить некоторый индикатор выполнения таким образом.

Но самый простой способ будет использовать Java собственные потоки и Android обработчик

final Handler handler = new Handler(); 
new Thread(new Runnable(){ 
    @Override 
    public void run(){ 
     final String json = fetchFromNetwork(); 
     handler.post(new runnable(){ 
      // finish callback (here is UI thread) 
      // do stuff with 'json' string 
     }); 
    } 
}).start(); 
0

Использование Volley.jar! он уже используют AsyncTask

private void makeJsonObjectRequest() { 

showpDialog(); 

JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.GET, 
     urlJsonObj, null, new Response.Listener<JSONObject>() { 

      @Override 
      public void onResponse(JSONObject response) { 
       Log.d(TAG, response.toString()); 

       try { 
        // Parsing json object response 
        // response will be a json object 
        String name = response.getString("name"); 
        String email = response.getString("email"); 
        JSONObject phone = response.getJSONObject("phone"); 
        String home = phone.getString("home"); 
        String mobile = phone.getString("mobile"); 

        jsonResponse = ""; 
        jsonResponse += "Name: " + name + "\n\n"; 
        jsonResponse += "Email: " + email + "\n\n"; 
        jsonResponse += "Home: " + home + "\n\n"; 
        jsonResponse += "Mobile: " + mobile + "\n\n"; 

        txtResponse.setText(jsonResponse); 

       } catch (JSONException e) { 
        e.printStackTrace(); 
        Toast.makeText(getApplicationContext(), 
          "Error: " + e.getMessage(), 
          Toast.LENGTH_LONG).show(); 
       } 
       hidepDialog(); 
      } 
     }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       VolleyLog.d(TAG, "Error: " + error.getMessage()); 
       Toast.makeText(getApplicationContext(), 
         error.getMessage(), Toast.LENGTH_SHORT).show(); 
       // hide the progress dialog 
       hidepDialog(); 
      } 
     }); 

// Adding request to request queue 
AppController.getInstance().addToRequestQueue(jsonObjReq); 

}

Android JSON parsing using Volley

0

Вы можете использовать нить с интерфейсом: Класс

Тема:

public class RequestTask extends Thread { 

    private ResultCallback callback; 

    public RequestTask(ResultCallback callback) { 
     this.callback = callback; 
    } 

    @Override 
    public void run() { 
     String result = ""; 
     // (Your request) 

     callback.onFinished(result); 
    } 

    public interface ResultCallback { 
     public void onFinished(String data); 
     public void onError(); 
    }  
} 

А где вы нужны данные :

RequestTask task = new RequestTask(new ResultCallback() { 
    @Override 
    public void onFinished(String data) { 
     //do something 
    } 

    @Override 
    public void onError() { 
     //show an error 
    } 
}); 
task.start(); 
+0

Вызов 'callback.onFinished (result);' в рабочем потоке, на мой взгляд, не является хорошая практика. Используйте «Обработчик», чтобы вызвать этот метод в основном потоке. –

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