我尝试使用改造来创建一个连接到服务器的服务。但每当我尝试连接时,它都无法达到回调成功或失败的方法。它确实得到了结果,但在达到成功或失败方法之前就停止了,所以它使我的应用程序没有响应。 我以前成功地使用过改造,但我没有使用服务,现在我需要在服务中做到这一点并且它不会工作。请帮我。 提前谢谢。
这是我的服务类:
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;
}
}
}
连接发生在函数Login中。
这是我的Api登录界面:
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
);
}
}
我的mainActivity里面调用了我的服务中的Login方法:
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));
}
}
}
我在服务连接后获得的响应:
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":"a@a.a","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":"a@a.a","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)
如上面的响应中所示,它在连接获得结果后结束,并且从不调用成功或失败方法。
答案 0 :(得分:0)
嗯,你不应该告诉主线程等待。这是不好的做法,也是你看到ANR的原因。而是在一个线程中进行,尽管异步调用的重点是你不需要等待。
如果您真的想进行阻止调用,为什么不重命名接口方法以返回对象而不是void。然后你可以按照同步方法,你不需要你的服务扩展回调(我不是btw的忠实粉丝)。
答案 1 :(得分:0)
就我而言,问题是Android Studio Emulator
。在真正的android设备onFailure
或onResponse
中始终被称为。
还向OkHttp
添加超时:
val httpClient = OkHttpClient.Builder()
.readTimeout(60, TimeUnit.SECONDS)
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build()