Android: How to wait IntentService for BroadcastReceiver onReceive method - android

I have IntentService that need to wait in method a() for results of onReceive() of BroadcastReceiver().
For now i use lmao wait(5000)... so it's not too elegant
IntentService:
private boolean methodA() {
try {
synchronized (mLocalBroadcastReceiver) {
mLocalBroadcastReceiver.wait(3000);
}
} catch (InterruptedException e) {
Log.e(TAG,"error, thread interrupted");
e.printStackTrace();
}
if(CONSTANT == true){
return true;
else
return false;
}
BroadCastRecievier:
#Override
public void onReceive(Context context, Intent intent) {
CONSTANT = true //changes somehow between true/false
}
In other words: return value of methodA depends on results of onReceive(). How to synchronize two threads?

Finally i used thread like that:
private void waitForResponse() {
//wait for response
thread = new WaitForStatus();
thread.run();
try {
synchronized (thread) {
thread.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class WaitForAppStatus implements Runnable {
#Override
public void run() {
while (true) {
if (CONSTANT != -1) {
break;
} else {
try {
wait(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

Related

Should I stop and recreate the thread or should I use wait() and notify() to deal with a game-loop, in Android?

how should I deal with the game loop when the user switches from my Android game to something else and then back?
Stopping and recreating the thread
Pausing/continuing the thread using wait() and notify()
Option #1 would look like this:
public void run() {
while (isRunning) {
// do stuff
}
}
#Override
protected void onPause() {
boolean retry = true;
gameLoop.setRunning(false);
while (retry) {
try {
mainThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
super.onPause();
}
#Override
protected void onResume() {
if (gameLoop.isRunning()) {
stop();
}
gameLoop.setRunning(true);
mainThread = new Thread(gameLoop);
mainThread.start();
super.onResume();
}
Option #2 would look like this:
public void run() {
while (!mFinished) {
// do stuff
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
#Override
protected void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
super.onPause();
}
#Override
protected void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
super.onResume();
}
Which option is the better one? And also should I use onPause()/onResume() or onStop()/onStart() to do these thread operations?
Thank you!

Number picker start changing value for few seconds

I would like a numberpicker to start changing the values automaticly for few seconds .
private void changeValueByOne(final NumberPicker higherPicker, final boolean increment) {
Method method;
try {
// refelction call for
// higherPicker.changeValueByOne(true);
method = higherPicker.getClass().getDeclaredMethod("changeValueByOne", boolean.class);
method.setAccessible(true);
method.invoke(higherPicker, increment);
} catch (final NoSuchMethodException e) {
e.printStackTrace();
} catch (final IllegalArgumentException e) {
e.printStackTrace();
} catch (final IllegalAccessException e) {
e.printStackTrace();
} catch (final InvocationTargetException e) {
e.printStackTrace();
}
}
I ve implemented this method and tried
Thread thread = new Thread() {
#Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
runOnUiThread(new Runnable() {
#Override
public void run() {
changeValueByOne(wp,true);
}
});
}
};
thread.start();
But it is not ok .
I would like to have an effect as a slot machine .
Why can't you simply set the value to an incremented value? Something like this:
private void changeValueByOne(final NumberPicker higherPicker) {
int oldValue = higherPicker.getValue();
higherPicker.setValue(oldValue++);
}
EDIT
Here is the source of the method you're reflecting:
private void changeValueByOne(boolean increment) {
if (mHasSelectorWheel) {
mInputText.setVisibility(View.INVISIBLE);
if (!moveToFinalScrollerPosition(mFlingScroller)) {
moveToFinalScrollerPosition(mAdjustScroller);
}
mPreviousScrollerY = 0;
if (increment) {
mFlingScroller.startScroll(0, 0, 0, -mSelectorElementHeight, SNAP_SCROLL_DURATION);
} else {
mFlingScroller.startScroll(0, 0, 0, mSelectorElementHeight, SNAP_SCROLL_DURATION);
}
invalidate();
} else {
if (increment) {
setValueInternal(mValue + 1, true);
} else {
setValueInternal(mValue - 1, true);
}
}
}
You can see that if mHasSelectorWheel = true, it calls the startScroll method. In other words, it sounds like your NumberPicker has mHasSelectorWheel = false, in which case you're out of luck given your current implementation. It is highly advisable that you look into a custom scrollable number picker widget.

How to implement cross process lock in android?

I'm writing a library project for multiple APPs to use. And for some reason, I must make a function mutual exclusion for different APPs, so I need a cross-process lock. But as far as I know, in android APPs can only write to it's own file's directory in internal storage, and external storage is unreliable because some device don't have one. So file lock seems not applicable for me, so is there any other way to implement cross-process lock?
thanks~
If you do not want to (or you can not) use flock or fcntl, maybe you can use LocalServerSocket to implement a spinlock.
For example:
public class SocketLock {
public SocketLock(String name) {
mName = name;
}
public final synchronized void tryLock() throws IOException {
if (mServer == null) {
mServer = new LocalServerSocket(mName);
} else {
throw new IllegalStateException("tryLock but has locked");
}
}
public final synchronized boolean timedLock(int ms) {
long expiredTime = System.currentTimeMillis() + ms;
while (true) {
if (System.currentTimeMillis() > expiredTime) {
return false;
}
try {
try {
tryLock();
return true;
} catch (IOException e) {
// ignore the exception
}
Thread.sleep(10, 0);
} catch (InterruptedException e) {
continue;
}
}
}
public final synchronized void lock() {
while (true) {
try {
try {
tryLock();
return;
} catch (IOException e) {
// ignore the exception
}
Thread.sleep(10, 0);
} catch (InterruptedException e) {
continue;
}
}
}
public final synchronized void release() {
if (mServer != null) {
try {
mServer.close();
} catch (IOException e) {
// ignore the exception
}
}
}
private final String mName;
private LocalServerSocket mServer;
}

Delay super.onbackpressed in android

I made a script which detects if there's internet connection:
public static boolean isOnline() {
try {
InetAddress.getByName("google.hu").isReachable(3);
return true;
} catch (UnknownHostException e){
return false;
} catch (IOException e){
return false;
}
}
If there's no internet the app will warn the user and the quit! But how to delay super.onBackPressed for 20 seconds? :)
this.toast1 = new Toast(getApplicationContext());
toast1.setGravity(Gravity.CENTER, 0, 0);
toast1.setDuration(20000);
toast1.setView(layout);
toast1.show();
super.onBackPressed();
Thread delayThread= new Thread(new Runnable()
{
#Override
public void run()
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
activityInstance.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
super.onBackPressed();
}
});
}
});
delayThread.start();
The easiest is to create a Handler in onCreate()and use postDelayed() with a Runnable that calls super.onBackPressed()

Using wait in AsyncTask

When using a wait in an AsyncTask, I get ERROR/AndroidRuntime(24230): Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Is it possible to use an Asynctask just for waiting? How?
Thanks
class WaitSplash extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
try {
wait(MIN_SPLASH_DURATION);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
waitSplashFinished = true;
finished();
}
}
Use Thread.sleep() instead of wait().
You can use Thread.sleep method
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Thread.currentThread();
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
If you're looking to just postpone execution of a method for a set amount of time, a good option is Handler.postDelayed()
define the handler and runnable...
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
finished();
};
and execute with delay...
handler.postDelayed(runnable, MIN_SPLASH_DURATION);
Use threads for this
public class SplashActivity extends Activity{
int splashTime = 5000;
private Thread splashThread;
private Context mContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mContext = this;
setContentView(R.layout.splash_layout);
splashThread = new Thread(){
public void run() {
try{
synchronized (this) {
wait(splashTime);
}
}catch(InterruptedException ex){
ex.printStackTrace();
}finally{
Intent i = new Intent(mContext,LocationDemo.class);
startActivity(i);
stop();
}
}
};
splashThread.start();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
synchronized (splashThread) {
splashThread.notifyAll();
}
}
return true;
}
on touch event, thread get notified.. can change according to your need.
You have this way to work with asyntask and wait();
public class yourAsynctask extends AsyncTask<Void, Void, Void> {
public boolean inWait;
public boolean stopWork;
#Override
protected void onPreExecute() {
inWait = false;
stopWork = false;
}
#Override
protected Void doInBackground(Void... params) {
synchronized (this) {
while(true) {
if(stopWork) return null;
if(youHaveWork) {
//make some
} else {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
public void mynotify() {
synchronized (this) {
if(inWait) {
notify();
inWait = false;
}
}
}
public void setStopWork() {
synchronized (this) {
stopWork = false;
if(inWait) {
notify();
inWait = false;
}
}
}
}

Categories

Resources