Monday, 15 April 2013

Android UI Thread freezes waiting for socket in a simple client/server architecture -



Android UI Thread freezes waiting for socket in a simple client/server architecture -

i think quite mutual problem, still didn't find satisfactory reply i'm going inquire myself.

this piece of code:

// insine onclickview textview status = (textview) findviewbyid(r.id.status); status.settext("trying connect server..."); seek { // opens socket , send login request server. int result = communicationmanager.login(string email, string password); switch (result) { case communicationmanager.success: // login ok, go on next screen break; case communicationmanager.wrong_email: status.settextcolor(color.red); status.settext("wrong email!"); break; case communicationmanager.wrong_password: status.settextcolor(color.red); status.settext("wrong password!"); break; } } grab (communicationexception e) { status.settextcolor(color.red); status.settext("unable estabilish connection!"); } grab (protocolexception e) { status.settextcolor(color.red); status.settext("protocol error!"); }

this achieve:

user click send button; status textview shows "trying connect server..."; ui "waits" communications over; status textview shows result accordingly.

but instead when user clicks send button, ui freezes (oddly before status text appears) until communication done (i tried connect unknown host). quick prepare set socket timeout, don't kind of solution: ui still freezes , timeout should set?

my first thought thread obviously, can see i need homecoming value, thing in threading environment doesn't create much sense since threads run independently , asynchronously.

so need ui waits service executed without freezing. way seems me waiting homecoming value means ui has to wait task over, not allow freeze.

i came across asynctask see 2 major disadvantages:

it seems me tightly coupled ui; what if want execute service integer, string , boolean parameters? should extend asynctask<object, void, void>?

both leads inextensibility.

what can accomplish goal? please note request service request not ready yet, should automatically repeat request every few time (let's 10 minutes). i'll need can utilize timertask, i'll still need homecoming value ui every time execute service (so can update status text , allow user know what's going on).

this typical utilize case while dealing through external communication i.e. http calls.

best way utilize asynctask. give answers concerns asynctask.

it seems me tightly coupled ui;

here code design play role. can write own phone call mechanism rid of tight coupling. illustration can below.

create version request , response need ws call. can simple primitive type or complex type parameters.

class result{ //define more para.

}

class request{ //deinf more para. }

write below callback interface.

public interface mycallback { public void oncomplete(result result);}

create asynctask , above interface object in constructor, same object can homecoming result object.

class longrunningtask extends asynctask<request, integer, long>{ private mycallback callback; public longrunningtask(mycallback callback) { super(); this.callback = callback; } @override protected long doinbackground(request... params) { // perform ground task. homecoming null; } @override protected void onpostexecute(long result) { super.onpostexecute(result); callback.oncomplete(new result()); //here result dummy in real should contructred doinbackground() method } }

now lastly , of import part implement interface , phone call asynctask. trying reuse code have improve clarity.

public class mainactivity extends activity implements mycallback{ @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); textview status = (textview) findviewbyid(r.id.status); status.settext("trying connect server..."); } private void onclick(){ //similer communicationmanager.login(string email, string password); in code. longrunningtask longrunningtask = new longrunningtask(this); longrunningtask.execute(new request()); } @override public void oncomplete(result result) { seek { int result = result.getstatus switch (result) { case communicationmanager.success: // login ok, go on next screen break; case communicationmanager.wrong_email: status.settextcolor(color.red); status.settext("wrong email!"); break; case communicationmanager.wrong_password: status.settextcolor(color.red); status.settext("wrong password!"); break; } } grab (communicationexception e) { status.settextcolor(color.red); status.settext("unable estabilish connection!"); } grab (protocolexception e) { status.settextcolor(color.red); status.settext("protocol error!"); } }

what if want execute service integer, string , boolean parameters? should extend asynctask?

first parameter user defined para. in case need pass multiple parameters set them in form of entity (i.e. - class). also, can pass initial configuration parameter in constructor of asynctask i.e. - communication url.

hope help.

android sockets client-server freeze

No comments:

Post a Comment