My code here works fine . It changes the image in my gallery at certain times , but i dont think this is the best approach , especially using thread.sleep() . How can i write a better code for that ? What am i missing ?
Thanks..
#Override
protected void onResume() {
paraThread = true;
workThread = new LooperFoto("MyWorkThread");
workThread.setPriority(Thread.MIN_PRIORITY);
workThread.start();
super.onResume();
}
#Override
protected void onStop() {
Log.i(TAG, "thread state: " + workThread.getState());
paraThread = false;
workThread = null;
super.onStop();
}
class LooperFoto extends HandlerThread {
public LooperFoto(String name) {
super(name);
}
#Override
public void run() {
while (paraThread) {
try {
this.sleep(2000);
mudaFoto.sendMessage(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Handler mudaFoto = new Handler() {
public void handleMessage(Message msg) {
Random generator = new Random();
int randomIndex = generator.nextInt(thumbImgGallery.getAdapter()
.getCount());
thumbImgGallery.setSelection(randomIndex);
};
};
As long as the thread that is .sleeping() is not your main (UI) thread, you should be fine. What are you worried about?
Related
I have a thread that running into an activity. I don't want that the thread continuos running when the user click the home button or, for example, the user receive a call phone.
So I want pause the thread and resume it when the user re-opens the application.
I've tried with this:
protected void onPause() {
synchronized (thread) {
try {
thread.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
super.onPause();
}
protected void onResume() {
thread.notify();
super.onResume();
}
It stops the thread but don't resume it, the thread seems freezed.
I've also tried with the deprecated method Thread.suspend() and Thread.resume(), but in this case into Activity.onPause() the thread doesn't stop.
Anyone know the solution?
Use wait() and notifyAll() properly using a lock.
Sample code:
class YourRunnable implements Runnable {
private Object mPauseLock;
private boolean mPaused;
private boolean mFinished;
public YourRunnable() {
mPauseLock = new Object();
mPaused = false;
mFinished = false;
}
public void run() {
while (!mFinished) {
// Do stuff.
synchronized (mPauseLock) {
while (mPaused) {
try {
mPauseLock.wait();
} catch (InterruptedException e) {
}
}
}
}
}
/**
* Call this on pause.
*/
public void onPause() {
synchronized (mPauseLock) {
mPaused = true;
}
}
/**
* Call this on resume.
*/
public void onResume() {
synchronized (mPauseLock) {
mPaused = false;
mPauseLock.notifyAll();
}
}
}
Try the below code it will work
Thread thread=null;
OnResume()
public void onResume(){
super.onResume();
if(thread == null){
thread = new Thread()
{
#Override
public void run() {
try {
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
}
onPause()
#Override
public void onPause(){
super.onPause();
if(thread != null){
Thread moribund = thread;
thread = null;
moribund.interrupt();
}
}
I have to update the list after optimizing the running apps ....
m_optimizeBtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
launchProgressRing(OptimizationActivity.this);
listAdaptor.notifyDataSetChanged();
}
});
}
Killing the running process in a seprate thread....
public void launchProgressRing(Context ctx){
final ProgressDialog opt_proDialog=new ProgressDialog(ctx);
opt_proDialog.setTitle("Please wait...");
opt_proDialog.setMessage("Optimizing power draining apps...");
opt_proDialog.setIndeterminate(true);
opt_proDialog.show();
opt_proDialog.setCancelable(false);
new Thread(new Runnable()
{
#Override
public void run()
{
//TODO: optimize apps
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
runOnUiThread(new Runnable()
{
#Override
public void run()
{
opt_proDialog.dismiss();
}
});
}
}).start();
}
listAdaptor.notifyDataSetChanged() is not working ,don't know why ???
What I suggest is to use AsyncTask to do the job. AsyncTask has two good methods for you:
doInBackground: which you can put most of the background tasks in there
onPostExecute : which you can put the logic of what needs to be done when the background task has finished its job.
So your code should look like this:
public class BackgroundTask extends AsyncTask<Void,Void,Void>{
private ListAdapter mAdapter;
public BackgroundTask(ListAdapter adapter)
{
mAdapter = adapter
}
public Void doInBackground (Void... params)
{
//define m_cPowerDrainingApps somewhere
m_cPowerDrainingApps.killBgRunningProcesses(runningAppsList);
try
{
Thread.sleep(1500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
public Void onPostExecute (Void... params)
{
//do your UI things
mAdapter.notifyDataSetChanged();
}
}
and then run this with:
new BackgroundTask(listAdapter).execute()
Use a Handler and its postDelayed method to invalidate the list's adapter as follows:
final Handler handler = new Handler()
handler.postDelayed( new Runnable() {
#Override
public void run() {
adapter.notifyDataSetChanged();
handler.postDelayed( this, 60 * 1000 );
}
}, 60 * 1000 );
You must only update UI in the main (UI) thread.
I was having some problem for Android activity transition. Basically what I am trying to do is share text to Twitter. However, when I open up the twitter content, it took quite a few seconds to load up the content and resulting in the white blank activity for a few seconds.
And here is my codes, when my button onClick, I am executing the loading dialog:
ivTwitterShare.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Thread newThread = new Thread() {
#Override
public void run() {
try {
super.run();
sleep(10000);
} catch (Exception e) {
} finally {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri
.parse(tweetUrl));
startActivity(intent);
progressDialog.dismiss();
}
}
};
newThread.start();
new LoadTwitterTask().execute();
}
});
private class LoadTwitterTask extends AsyncTask<Void, Integer, Void> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(context, "Loading Twitter...",
"Retrieving Twitter information, please wait...", false,
false);
EventDialogueBox.customizeDialogueBox(context, progressDialog);
}
#Override
protected Void doInBackground(Void... params) {
try {
synchronized (this) {
int counter = 0;
while (counter <= 4) {
this.wait(50);
counter++;
publishProgress(counter * 25);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result) {
}
}
However, my problem now is the white blank page before the content is loaded up still there. What I wanted is firstly, the loading dialog will show. Then, at the same time, the twitter intent is loading. Once finish loaded up the content, then dialog will be dismissed.
Any ideas?
Thanks in advance.
i'm trying to add markers to my map, the coordinates and names are contained in a stop object that i'm getting through a query to a stackmob database, the program runs fine displays the map, but for some reason it looks like its not executing the addmarker instruction, won't even loop through the for in the addMarkers method. Also i'm not getting errors or messages of any kind in the console or LogCat, i'm running out of ideas to solve this.
public class MainActivity extends Activity {
GoogleMap map;
List<Stop> stops=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
StackMobAndroid.init(getApplicationContext(), 0, "f4e013f5-3e0f-41e2-af2f-3fc2bfa2446b");
getMarkers();
}
public void getMarkers( )
{
Stop.query(Stop.class, new StackMobQuery().field(new StackMobQueryField("stop")), new StackMobQueryCallback<Stop>() {
#Override
public void success(List<Stop> result) {
addMarkers(result);
}
#Override
public void failure(StackMobException e) {
System.out.println("Fail");
}
});
}
public void addMarkers(List<Stop> stops)
{
for(int i=0;i<=stops.size();i++)
{
LatLng markerPos = new LatLng(stops.get(i).getLatitude(), stops.get(i).getLongitude());
System.out.println(markerPos);
System.out.println(stops.get(i).getName());
System.out.println(i);
map.addMarker(new MarkerOptions().title(stops.get(i).getName()).snippet("test").position(markerPos));
}
}
Thanks
Edit: If i add a a marker manually in, lets say the onCreate method, it will display correctly on the map.
Edit2: When i put a try catch statement around the map.addmarker the error message reads "Not on the main thread" not sure about this.
Okay so i found the solution, apparently the stackmob query runs on a separate thread so if yo want to modify an ui element, like the map in this case , you have to call a runonUithread from the success method.
public void getMarkers( )
{
Stop.query(Stop.class, new StackMobQuery().field(new StackMobQueryField("stop")), new StackMobQueryCallback<Stop>() {
#Override
public void success(List<Stop> result) {
runThread(result);
}
#Override
public void failure(StackMobException e) {
System.out.println("Fail");
}
});
}
private void runThread(final List<Stop> stops) {
new Thread() {
public void run() {
int i=0;
while (i++ < 1) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
for(int j=0;j<stops.size();j++)
{
LatLng markerPos = new LatLng(stops.get(j).getLatitude(), stops.get(j).getLongitude());
System.out.println(markerPos);
System.out.println(stops.get(j).getName());
System.out.println(j);
try {
map.addMarker(new MarkerOptions().title(stops.get(j).getName()).snippet("test").position(markerPos));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
});
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
I'm havin difficulties of keeping track of my queue.
I'm trying to store image-paths into a queue so i can use the queue to start uploading my images once there's internet (at a later moment). The upload image is an asynctask and in the postExecute i'm trying to send a mail with the uploaded picture attached to it in another asynctask.
This is my UploadImage AsyncTask. I think i'm doing way too difficult and that it can be done much easier than it is right now.
private class UploadImageTask extends AsyncTask<Void, Void, Integer> {
ProgressDialog dialog;
/**
* Private integer which counts how many times we've tried to upload the
* Image.
*/
private int _counter = 0;
private List<String> imageUploadList = new ArrayList<String>();
#Override
protected void onPreExecute() {
super.onPreExecute();
if(AppStatus.haveNetworkConnection(_context)){
if(isPhotoTaken()){
dialog = new ProgressDialog(Step4.this);
dialog.setCancelable(false);
dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.setMessage(getString(R.string.uploadingMessage));
dialog.setTitle(getString(R.string.uploadingTitle));
dialog.show();
}
}
}
protected Integer doInBackground(Void... params) {
init();
postData();
return null;
}
public void init(){
_counter = 0;
_beenHere = true;
for(String path : imageUploadList){
Debug.out("Path: "+path);
}
}
public void postData() {
if (isPhotoTaken()) {
if(AppStatus.haveNetworkConnection(_context)){
if(_beenHere){
ImageUploader.uploadFile(getPhotoPath(),
"http://obo.nl/android-upload-image.php", Step4.this);
} else {
for(String path : imageUploadList){
Debug.out(path);
ImageUploader.uploadFile(path,
"http://obo.nl/android-upload-image.php", Step4.this);
}
}
} else {
if (_counter == 0) {
_counter++;
_activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(_context,
getString(R.string.noInternetImageNotUploaded),
Toast.LENGTH_LONG).show();
}
});
imageUploadList.add(getPhotoPath());
}
try {
if(_beenHere){
_beenHere = false;
goToNextIntent();
}
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
postData();
}
}
}
private void goToNextIntent(){
Intent intent = new Intent(Step4.this, Step5.class);
intent.putExtra(EXTRA_MESSAGE, (Serializable) _user);
intent.putExtra(EXTRA_MESSAGE2, _isRepairable);
intent.putExtra(EXTRA_MESSAGE3, _injury);
intent.putExtra(EXTRA_MESSAGE4, _category);
intent.putExtra(EXTRA_MESSAGE5, _inch);
intent.putExtra(EXTRA_MESSAGE6, _size);
startActivity(intent);
}
protected void onPostExecute(Integer result) {
if(isPhotoTaken()){
if(dialog != null){
dialog.dismiss();
}
}
mailing(_isRepairable);
new MyAsyncTask().execute(_mail);
}
}
The line:
if(AppStatus.haveNetworkConnection(_context))
returns a boolean true if the user has a working internet connection. false otherwise.
What I want is to queue all the image paths (and mails sent afterwards) in the desired ArrayList so i can send them all at a later moment when the user has a working internet Connection. Please help me out!