Reputation: 469
I try to make a service that will connect to server using retrofit. But whenever I try to connect, it doesn't reach the callback success or failure methods. It does get the result but then it stopped before reaching success or failure methods so it makes my app not responding. I've done successfully using retrofit before but I didn't use service, and now I need to do this inside a service and it won't work. Please help me. Thanks in advance.
Here is my service class:
public class ConnectionService extends Service implements Messaging,UserManagement, Callback<Response>{
public final IBinder myBinder = new MyBinder();
public final RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Api.API_URL)
.setClient(new OkClient(new OkHttpClient()))
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
private String jsonResponse = "";
private final Object object = new Object();
private Gson gson = new Gson();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
@Override
public boolean getInbox(String token, long limit, long page) {
return false;
}
@Override
public boolean getMessage(String token, int id_member, long limit, long page) {
return false;
}
@Override
public boolean sendMessage(String token, int id_teman, String message) {
return false;
}
@Override
public boolean hideMessage(String token, long id_message) {
return false;
}
@Override
public boolean getToyotaMessage(String token, long limit, long page) {
return false;
}
@Override
public void showNotification(String message) {
}
@Override
public boolean Signup(String fullname, String email, String password) {
return false;
}
@Override
public Me Login(String email, String password) {
Me me = new Me(email,password);
Api.Login login = restAdapter.create(Api.Login.class);
login.fetch(me,this);
try{
synchronized (object){
object.wait();
if(jsonResponse != null && !jsonResponse.equals("")){
Type tipe = new TypeToken<ApiResponse<Me>>(){}.getType();
ApiResponse<Me> apiResponse = gson.fromJson(jsonResponse,tipe);
Metadata metadata = apiResponse.metadata;
if(metadata.code==200){
return apiResponse.data.get(0);
}
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
public void success(Response response, Response response2) {
synchronized (object){
jsonResponse = Utils.convertResultToString(response);
Log.d(ConnectionService.class.getSimpleName(),"Success. Response: "+jsonResponse);
object.notifyAll();
}
}
@Override
public void failure(RetrofitError retrofitError) {
synchronized (object){
jsonResponse = null;
object.notifyAll();
}
}
public class MyBinder extends Binder{
public ConnectionService getInstance(){
return ConnectionService.this;
}
}
}
The connection happens inside function Login.
Here's my Api Login interface:
public class Api {
public interface Signup{
@POST(Methods.SIGNUP)
void fetch(
@Body Me me,
Callback<Response> callback
);
}
public interface Login{
@POST(Methods.LOGIN)
void fetch(
@Body Me me,
Callback<Response> callback
);
}
}
And here's inside my mainActivity that calls Login method inside my service:
public class MainActivity extends ActionBarActivity {
public boolean isLoggedin = false;
public Me me = null;
public ConnectionService myService;
public ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(MainActivity.class.getSimpleName(),"On Service Connected");
myService = ((ConnectionService.MyBinder)iBinder).getInstance();
login();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(MainActivity.class.getSimpleName(),"On Service Connected");
myService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private void login(){
if(myService != null) {
me = myService.Login(Settings.EMAIL, Settings.cred);
if (me != null) {
Log.d(MainActivity.class.getSimpleName(), "full name: " + me.fullname);
isLoggedin = true;
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onStart() {
super.onStart();
if(myService == null){
bindService(new Intent(this,ConnectionService.class),serviceConnection, Context.BIND_AUTO_CREATE);
//startActivity(new Intent(this,ConnectionService.class));
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if(myService != null){
unbindService(serviceConnection);
//stopService(new Intent(this,ConnectionService.class));
}
}
}
Response that I get after on Service Connected:
05-25 14:31:42.954 7006-7006/com.subkhansarif.connecionmodule D/MainActivity﹕ On Service Connected
05-25 14:31:42.993 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ ---> HTTP POST http://103.247.10.71/imsave/v3/account/login
05-25 14:31:42.993 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Content-Type: application/json; charset=UTF-8
05-25 14:31:42.993 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Content-Length: 57
05-25 14:31:42.993 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ {"email":"[email protected]","password":"a","id_member":0,"points":0}
05-25 14:31:42.993 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ ---> END HTTP (57-byte body)
05-25 14:31:43.180 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
05-25 14:31:43.180 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule I/dalvikvm﹕ Could not find method java.nio.file.Files.newOutputStream, referenced from method okio.Okio.sink
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to resolve static method 19323: Ljava/nio/file/Files;.newOutputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/OutputStream;
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x000a
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to find class referenced in signature (Ljava/nio/file/Path;)
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to find class referenced in signature ([Ljava/nio/file/OpenOption;)
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule I/dalvikvm﹕ Could not find method java.nio.file.Files.newInputStream, referenced from method okio.Okio.source
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule W/dalvikvm﹕ VFY: unable to resolve static method 19322: Ljava/nio/file/Files;.newInputStream (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Ljava/io/InputStream;
05-25 14:31:43.188 7006-7020/com.subkhansarif.connecionmodule D/dalvikvm﹕ VFY: replacing opcode 0x71 at 0x000a
05-25 14:31:43.813 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ <--- HTTP 200 http://103.247.10.71/imsave/v3/account/login (820ms)
05-25 14:31:43.813 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Date: Mon, 25 May 2015 07:31:43 GMT
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Server: Apache/2.4.10 (Unix) OpenSSL/1.0.1j PHP/5.6.3 mod_perl/2.0.8-dev Perl/v5.16.3
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ X-Powered-By: PHP/5.6.3
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Content-Length: 750
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Content-Type: application/json
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ X-Cache: MISS from webcache.cnrglab.itb.ac.id
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ X-Cache-Lookup: MISS from webcache.cnrglab.itb.ac.id:3128
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ X-Cache: MISS from webcache-ng.cnrglab.itb.ac.id
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ X-Cache-Lookup: MISS from webcache-ng.cnrglab.itb.ac.id:3128
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Via: 1.1 webcache.cnrglab.itb.ac.id (squid/3.5.4-20150510-r13825), 1.1 webcache-ng.cnrglab.itb.ac.id (squid/3.5.3)
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ Connection: keep-alive
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ OkHttp-Selected-Protocol: http/1.1
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ OkHttp-Sent-Millis: 1432539103202
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ OkHttp-Received-Millis: 1432539103816
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ {"metadata":{"code":200,"message":"OK","timestamp":"2015-05-25 14:31:43"},"data":[{"image":{"href":"http:\/\/103.247.10.71\/imsave\/assets\/member_image\/174","mime_type":""},"id_member":174,"fullname":"a","email":"[email protected]","phone":"4","birthday":null,"gender":null,"address":null,"city":null,"province":null,"country":"INDONESIA","zip":null,"latitude":null,"longitude":null,"location":null,"device":"EMAIL","login_method":"FB","points":20,"level":"1","badges":[],"created":"2015-05-22 19:29:34","token":"Un87jGj8DB6Q1Jhf08Acct1nsewQC0dwnlEG1YOFzVvAFNQFWrS8UTwn73dK3rgqMV7OTWttSZ4xMVdJm6Sh0oE8rRSvj9V543UYZorSowqbrEUNKM4KbJSCBL7UU30Y6UW6joZHUpSl3N9NzeyKXrnzcvt6yt5Fo2MHqLplaiHe5R2F6Aq42NDej6lRzqxYtkGU65fh"}],"pagination":{"page":1,"limit":1,"size":1}}
05-25 14:31:43.821 7006-7020/com.subkhansarif.connecionmodule D/Retrofit﹕ <--- END HTTP (750-byte body)
as seen in response above, it ends up after connection gets the result and never invoke success or failure methods.
Upvotes: 2
Views: 5107
Reputation: 1014
In my case the problem was Android Studio Emulator
. in real android device onFailure
or onResponse
always called .
also add timeout to OkHttp
:
val httpClient = OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build()
Upvotes: 1
Reputation: 4086
Well you shouldn't tell the main thread to wait. That's bad practice and is the reason you're seeing the ANR. Instead do it in a thread, though the point of the async call is that you don't need to wait.
If you really wanted to make a blocking call, why not rename your interface methods to return objects rather than void. Then you can follow the synchronous approach and you won't need your service extending Callback (which I'm not a big fan of btw).
Upvotes: 0