Server response Timeout function in parse.com android - android

I am working on parse.com android application. Like in normal http request if we don't get the response from the server in a certain time then it will show time out functionality. For example my following code will works for http request time out:
HttpsURLConnection connection = null;
connection = (HttpsURLConnection) serverAddress.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setHostnameVerifier(DO_NOT_VERIFY);
connection.setReadTimeout(3*1000);
Now i want the same functionality in parse.com, if i can't get the response from the parse server because of any reason like internet connectivity issue, then it will gives me timeout.
Thanks in advance.

Parse.com SDK does not have such functionality which you have described at your question.
But you can do some trick, for example, at ParseQuery exists method cancel(). So if you want timeout less then standard one, you can run query in background and and wait until or query callback will delivery result of it, or your implementation of timeout will cancel query running.
Update:
public class TimeoutQuery<T extends ParseObject> {
private ParseQuery<T> mQuery;
private final long mTimeout;
private FindCallback<T> mCallback;
private final Object mLock = new Object();
private final Thread mThread;
public TimeoutQuery(ParseQuery<T> query, long timeout) {
mQuery = query;
mTimeout = timeout;
mThread = new Thread() {
#Override
public void run() {
if (isInterrupted()) return;
try {
Thread.sleep(mTimeout);
} catch (InterruptedException e) {
return;
}
cancelQuery();
}
};
}
private void cancelQuery() {
synchronized (mLock) {
if (null == mQuery) return; // it's already canceled
mQuery.cancel();
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
mCallback.done(Collections.<T>emptyList(), new ParseException(ParseException.TIMEOUT, ""));
}
});
}
}
public void findInBackground(final FindCallback<T> callback) {
synchronized (mLock) {
mCallback = callback;
mQuery.findInBackground(new FindCallback<T>() {
#Override
public void done(List<T> ts, ParseException e) {
synchronized (mLock) {
mThread.interrupt();
mQuery = null;
mCallback.done(ts, e);
}
}
});
mThread.start();
}
}
}
Usage:
ParseQuery<ParseObject> query = ParseQuery.getQuery("Test");
new TimeoutQuery<>(query, 1000).findInBackground(new FindCallback<ParseObject>() {
...
});

Related

Can't create handler inside thread that has not called Looper.prepare(), while implementing IdlingResource

I’m attempting to write Espresso unit test that depends on a component that makes TCP/IP network connection to an external app in order to pass successfully.
The test failed to due the fact that the TCP/IP network took longer than the allowed by Espresso...
Therefore, we need to have TCP/IP code Class TCPConnectionTask implement IdlingResource:
However, I'm getting, this exception:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Activity.<init>(Activity.java:786)
at com.sample.QuicksetSampleActivity.<init>(QuicksetSampleActivity.java:82)
at com.unitTests.QuicksetSampleActivityTest.<init>(QuicksetSampleActivityTest.java:52)
I enclosed the TCPConnectionTask and called Looper.prepare() & also attempted Looper.prepareMainLooper() , with no success, see below (TCPConnectionTask):
/**
* Async task to connect to create TCPIPDataComm and connect to external IRB.
*
*/
public class TCPConnectionTask extends AsyncTask<String, Void, Void > implements IdlingResource {
String ip_user = null;
int port_user;
private ResourceCallback callback;
private boolean flag = false;
protected Void doInBackground(String... args) {
try {
Handler handler = new Handler(Looper.getMainLooper());
handler.post(
new Runnable() {
#Override
public void run() {
Looper.prepare();
//Looper.prepareMainLooper();
flag = true;
TCPIPDataComm tcp = new TCPIPDataComm(ip_user, port_user);
if(tcp != null){
tcp.open();
_TCPDataComm = tcp;
// we can enable the DataComm interface for simulation in UI app
int resultCode = 0;
try {
resultCode = QuicksetSampleApplication.getSetup().setDataCommInfo(
getAuthKey(), _TCPDataComm.getHostName(),
_TCPDataComm.getPortNumber());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
//task completed
flag = false;
}
Log.d(QuicksetSampleActivity.LOGTAG,
"Setting DataComm Result = "
+ resultCode
+ " - "
+ ResultCode
.getString(resultCode));
}
}
}
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void setInfo(String ipValue, int portNumber)
{
ip_user = ipValue;
port_user = portNumber;
}
#Override
public String getName() {
return this.getClass().getName().toString();
}
#Override public boolean isIdleNow() {
if (flag && callback != null) {
callback.onTransitionToIdle();
}
return flag;
}
#Override public void registerIdleTransitionCallback(ResourceCallback callback) {
this.callback = callback;
}
}
Below is the relevant snippet of the unit test class, QuicksetSampleActivityTest:
#RunWith(AndroidJUnit4.class)
public class QuicksetSampleActivityTest extends ActivityInstrumentationTestCase2<QuicksetSampleActivity> {
private QuicksetSampleActivity newQuicksetSampleActivity = null;
private final String ip = "192.168.43.139";
private final int port = 9999;
private final int timeOutTime = 1000;
//This is the idling resource that takes time to complete due to network latency...
private QuicksetSampleActivity.TCPConnectionTask taskIdlingResource = null;
//const
public QuicksetSampleActivityTest() {
super(QuicksetSampleActivity.class);
//instantiation of idling resource that is used for TCP connection
taskIdlingResource = new QuicksetSampleActivity().new TCPConnectionTask();
}
#Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
//open activity
newQuicksetSampleActivity = getActivity();
// Make sure Espresso does not time out
IdlingPolicies.setMasterPolicyTimeout(timeOutTime * 10, TimeUnit.MILLISECONDS);
IdlingPolicies.setIdlingResourceTimeout(timeOutTime * 10, TimeUnit.MILLISECONDS);
//register idling resource
Espresso.registerIdlingResources(taskIdlingResource);
}
#After
public void unregisterIntentServiceIdlingResource() {
//unregister idling resource
Espresso.unregisterIdlingResources(taskIdlingResource);
}
//The EditText GUI with the port & Ip was noe found using espresso, we need to set teh ip & port programmatically
public void setIpandPortToPcBridge() {
// Use TCPCommunicatuonTask interface
taskIdlingResource.setInfo(ip, port);
taskIdlingResource.execute();
}
//after TCP connection is made and/or tested
#Test
public void testActionBarMenuItemsIrDevicesAfterTCPConnectionFunctions() {
//we were not able to find the IP & Port fields so set them programmatically
setIpandPortToPcBridge();
//open action bar menu
Espresso.openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
//test IR Devices/Functions menu item
Espresso.onData(Matchers.allOf(Matchers.instanceOf(MenuItem.class), MatcherUtility.menuItemWithTitle("IR Devices/Functions"))).perform(ViewActions.click());
//add new device will connect the app
Espresso.onView(ViewMatchers.withId(R.id.btAdd)).perform(ViewActions.click());
//DeviceFunctionsActivity is rendered
Espresso.onView(ViewMatchers.withText("IR Devices")).check(ViewAssertions.matches(ViewMatchers.withText("IR Devices")));
//find the 3 required buttons for this UI
//test START learning
//Espresso.onView(ViewMatchers.withText("Start")).check(ViewAssertions.matches(ViewMatchers.withText("Start")));
//click
//test CANCEL learning
//test TEST Learned IR
//Espresso.onView(ViewMatchers.withText("Test Learned IR")).check(ViewAssertions.matches(ViewMatchers.withText("Test Learned IR")));
//click
//test Delete Learn Code
// Espresso.onView(ViewMatchers.withText("Delete Learn Code")).check(ViewAssertions.matches(ViewMatchers.withText("Delete Learn Code")));
//click
//go back
//ViewActions.pressBack();
}
}
}
How can I resolve this exception, and run the Espresso IdlingResource successfully?
Try
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
// Your testActionBarMenuItemsIrDevicesAfterTCPConnectionFunctions() test body
}
});
Example of usage with ActivityTestRule:
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
mMusicPlayerActivityTestRule.getActivity()
.getSupportMediaController().registerCallback(
new MediaControllerCompat.Callback() {
#Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {
super.onPlaybackStateChanged(state);
if (state.getState() == STATE_PLAYING) {
countDownLatch.countDown();
}
}
});
}});

Send the string to url with Android and get response in EditText

I need to use this api,
"http://sconysoft.com/api/md5.php?q="
for doing something like this app :
https://play.google.com/store/apps/details?id=com.sconysoft.md5encoderdecoder&hl=en
Actually, i have one button with Two EditText in Android app, just i need send first string to this api, and if this hash encoded(in url) exist, show that in Edit Text2.
and this is above app Codec class :
public class Codec {
public String decode(String md5) throws Exception {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(new HttpGet("http://sconysoft.com/api/md5.php?q=" + md5));
BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
JSONObject jo = new JSONObject(br.readLine());
if(jo.getString("md5").equals(""))
throw new Exception();
return jo.getString("word");
} catch (Exception e) {
}
throw new Exception("Can't decode given md5");
}
}
main :
public boolean isNetworkAvailable() {
ConnectivityManager cm = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
public void decode(View view) {
final EditText etWord = (EditText)findViewById(R.id.edit1);
final EditText etMd5 = (EditText)findViewById(R.id.edit2);
if(!isNetworkAvailable()) {
etWord.setText("Network unavailable");
return;
}
final ProgressDialog pd = ProgressDialog.show(view.getContext(),"Waiting for Server", "It should take a few seconds");
Thread th = new Thread() {
#Override
public void run() {
try {
Codec cd = new Codec();
String md5 = etMd5.getText().toString();
try {
final String word = cd.decode(md5);
runOnUiThread(new Runnable() {
public void run() {
etWord.setText(word);
pd.dismiss();
}
});
} catch (final Exception e) {
runOnUiThread(new Runnable() {
public void run() {
etWord.setText(e.getMessage());
pd.dismiss();
}
});
}
} catch(Exception e) {
runOnUiThread(new Runnable() {
public void run() {
pd.dismiss();
}
});
}
}
};
th.start();
}
}
i also try this codes with same situation in developing, but unfortunately, this codes doesn't work and i cannot see this buttons codes or other something on this app codes.
Can someone help me, how to doing this with one button and Two EditTexts?
Need some help about doing this with above API.
I am assuming
public void decode(View view)
gets called from the button onClick?
I suggest doing the network call (and managing the progress dialog) in an AsyncTask. Examples:
Using AsyncTask for android network connection
How to use AsyncTask to show a ProgressDialog while doing background work in Android?
You update the second EditText (you could use TextView) in the AsyncTask's onPostExecute.

AsyncTask in an android socket application

i am making an android socket app to communicate with the server for creating accounts, and i noticed i have to do this in AsyncTask sub class, even when i seperate it to another class without UI,but i am terribly confused how can i use AsyncTask on this, is there any one expert here who can help me please?
this is the code:
public class AccountCreator extends Activity {
public AccountCreator(){
super();
}
// for I/O
ObjectInputStream sInput; // to read from the socket
ObjectOutputStream sOutput; // to write on the socket
Socket socket;
public static String LOGTAG="Lifemate";
public String server = "localhost";
public String username = "user";
public String password = "rezapassword" ;
public int port = 1400;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(LOGTAG,"oncreate called");
this.start();
}
AccountCreator(String server, int port, String username,String password) {
this.server = "localhost";
this.port = 1400;
this.username = username;
Log.i(LOGTAG,"first accountcreator called");
}
public boolean start() {
// try to connect to the server
//this method returns a value of true or false when called
try {
socket = new Socket(server, port);
}
// if it failed not much I can so
catch(Exception ec) {
// display("Error connectiong to server:" + ec);
Log.i(LOGTAG,"Error connectiong to server:" + ec);
return false;
}
String msg = "Connection accepted " + socket.getInetAddress() + ":" +
socket.getPort();
// display(msg);
Log.i(LOGTAG, msg);
/* Creating both Data Stream */
try
{
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException eIO) {
// display("Exception creating new Input/output Streams: " + eIO);
Log.i(LOGTAG,"Exception creating new Input/output Streams: " +
eIO);
return false;
}
// creates the Thread to listen from the server
// Send our username to the server this is the only message that we
// will send as a String. All other messages will be ChatMessage objects
try
{
sOutput.writeObject(username);
sOutput.writeObject(password);
}
catch (IOException eIO) {
// display("Exception doing login : " + eIO);
Log.i(LOGTAG,"Exception doing login : " + eIO);
disconnect();
return false;
}
// success we inform the caller that it worked
return true;
}
// private void display(String msg) {
// TextView screenprint = (TextView)findViewById(R.id.systemmessages);
// screenprint.setText(msg);
// }
private void disconnect() {
Log.i(LOGTAG,"reached disconnect");
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {} // not much else I can do
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {} // not much else I can do
try{
if(socket != null) socket.close();
}
catch(Exception e) {} // not much else I can do
}
public void Begin() {
Log.i(LOGTAG,"it begun");
int portNumber = 1400;
String serverAddress = server;
String userName = username;
String newpassword = password;
AccountCreator accountcreator = new AccountCreator(serverAddress, portNumber,
userName,password);
if(!accountcreator.start())
return;
}
}
i was trying to put whole code in Async, i dont know if was i right, do i need to do that also or just some parts of it?
In brief, AsyncTask contains a few methods which may be helpful:
onPreExecute:
This method is the first block of code executed when calling asyncTask.execute(); (runs on mainUIThread).
doInBackground:
Here you put all the code which may suspend you main UI (causes hang for your application) like internet requests, or any processing which may take a lot of memory and processing. (runs on background thread), contains one parameter taken from the asyncTask.execute(ParameterType parameter);
onPostExecute
Runs after doInBackground(). Its parameter is the return value of the doInBackground function, and mainly you put the changes in UI need to be done after the connection is finished (runs on mainUIThread)
You have to declare another class within the class you have already created.
class SomeName extends Async<Void, String, Void>{
protected void OnPreExecute(){
// starts the task runs on main UI thread
// Can be used to start a progress dialog to show the user progress
}
#Override
protected Void doInBackground(Void... params){
// does what you want it to do in the background
// Connected to the server to check a log-in
return result;
}
protected void OnPostExecute(Void result){
// finishes the task and can provide information back on the main UI thread
// this would be were you would dismiss the progress dialog
}
}

Second time running the thread makes application crash

I use a worker thread to read text from a url. My thread is as follow. In the first time running, I am sure thread running is finished as I can check sdcard_readstr is null.
In the second time running, when I call thread_download.start();, then the program crashed.
What could be wrong? Thanks
public class DownloadingThread extends AbstractDataDownloading {
#Override
public void doRun() {
// TODO Auto-generated method stub
try {
// Create a URL for the desired page
URL url = new URL(SDcard_DetailView.textfileurl);
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new
InputStreamReader(url.openStream()));
do{
sdcard_readstr = in.readLine();
}while(sdcard_readstr!=null);
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
}
}
public abstract class AbstractDataDownloading extends Thread{
private final Set<ThreadCompleteListener> listeners
= new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
#Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}
public abstract void doRun();
}
EDIT1:
In my thread complete notification, I use runOnUiThreadto use the UI components.
Is that causing problem?
public void notifyOfThreadComplete(Thread thread) {
// TODO Auto-generated method stub
if(downloadingStopbuttonispressed == false){//background process completed
textfileurl = null;
this.runOnUiThread(new Runnable() {
public void run() {
Wifibutton = (Button) findViewById(R.id.Wifiscanning);
Wifibutton.setText("Load another day's data");
final MenuItem refreshItem = optionsMenu.findItem(R.id.airport_menuRefresh);
refreshItem.setActionView(null);
}
});
}
}
I called thread start in onResume() as
#Override
protected void onResume() {
super.onResume();
if(textfileurl != null){
Wifibutton.setText("Stop Data Loading");
buttonStatus = "loading";
setRefreshActionButtonState(true);
thread_download.start();
}
}
EDIT2:
My LogCat image is attached.
My solution is here . I can't reuse the same instance of the Thread object in the second time. I need to create a new instance to call the Thread in the second time. So Thread is suitable for single time running process, for multiple time running process I should use AsyncTask. Even AsyncTack is only for one time execution and for multiple time execution, we should use as new MyAsyncTask().execute(""); I don't understand why people downvote with no reason given. I couldn't find the link in my first search.

Timing issue in an Android JUnit test when observing an object modifed by another thread

My Android app should do the following:
The MainActivity launches another thread at the beginning called UdpListener which can receive UDP calls from a remote server. If it receives a packet with a content "UPDATE", the UdpListener should notify the MainActivity to do something.
(In the real app, the use case looks like this that my app listens on the remote server. If there is any new data available on the remote server, it notifies every client (app) by UDP, so the client knows that it can download the new data by using HTTP).
I tried to simulate this in an JUnit test. The test contains an inner class which mocks the MainActivity as well as it sends the UDP call to the UdpListener:
public class UdpListener extends Thread implements Subject {
private DatagramSocket serverSocket;
private DatagramPacket receivedPacket;
private boolean running = false;
private String sentence = "";
private Observer observer;
private static final String TAG = "UdpListener";
public UdpListener(Observer o) throws SocketException {
serverSocket = new DatagramSocket(9800);
setRunning(true);
observer = o;
}
#Override
public void run() {
setName(TAG);
while (isRunning()) {
byte[] receivedData = new byte[1024];
receivedPacket = new DatagramPacket(receivedData, receivedData.length);
try {
serverSocket.receive(receivedPacket);
}
catch (IOException e) {
Log.w(TAG, e.getMessage());
}
try {
sentence = new String(receivedPacket.getData(), 0, receivedPacket.getLength(), "UTF-8");
if ("UPDATE".equals(sentence)) {
notifyObserver();
}
}
catch (UnsupportedEncodingException e) {
Log.w(TAG, e.getMessage());
}
}
}
private boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
#Override
public void notifyObserver() {
observer.update();
}
}
This is the corresponding test:
#RunWith(RobolectricTestRunner.class)
public class UdpListenerTest {
private MainActivityMock mainActivityMock = new MainActivityMock();
#Before
public void setUp() throws Exception {
mainActivityMock.setUpdate(false);
}
#After
public void tearDown() throws Exception {
mainActivityMock.setUpdate(false);
}
#Test
public void canNotifyObserver() throws IOException, InterruptedException {
UdpListener udpListener = new UdpListener(mainActivityMock);
udpListener.setRunning(true);
udpListener.start();
InetAddress ipAddress = InetAddress.getByName("localhost");
DatagramSocket datagramSocket = new DatagramSocket();
DatagramPacket sendPacket = new DatagramPacket("UPDATE".getBytes(), "UPDATE".length(), ipAddress, 9800);
datagramSocket.send(sendPacket);
datagramSocket.close();
assertTrue(mainActivityMock.isUpdate());
udpListener.setRunning(false);
}
private class MainActivityMock implements Observer {
private boolean update = false;
#Override
public void update() {
update = true;
}
public boolean isUpdate() {
return update;
}
public void setUpdate(boolean update) {
this.update = update;
}
}
}
The good thing is that my concept works. But, this test doesn't. That means it only does when I stop with a breakpoint at this line datagramSocket.close(); and wait for about a second. Why this happens is clear. But how can I do that automatically? I thought about using wait() but I have to invoke notify() from the other thread for that. The same problem with CountDownLatch. I'm not sure how to solve that without changing UdpListener.
You could write a simple loop with a specified timeout.
try {
long timeout = 500; // ms
long lastTime = System.currentTimeMillis();
while(timeout > 0 && !mainActivityMock.isUpdate()) {
Thread.sleep(timeout);
timeout -= System.currentTimeMillis() - lastTime;
lastTime = System.currentTimeMillis();
}
} catch(InterruptedException e) {
} finally {
assertTrue(mainActivityMock.isUpdate());
}
By the way - you should declare your running attribute to volatile.
one solution would be to use a blocking queue with size 1 for storing your received results.
The request for isUpdate (which would take an element from the blocking queue) would block until the update package(or any other package) is put into the queue.
is case you want all your calls to be non-blocking you could use a Future for receiving your result. Future.get() would block ontil your result is received.

Categories

Resources