cannot upload image onto server without using UI thread - android

public void upload_prescription()
{
dialog = ProgressDialog.show(MainActivity.this, "","Uploading file...", true);
new Thread(new Runnable()
{
public void run()
{
runOnUiThread(new Runnable()
{
public void run()
{
// option1 upload_image.uploadFile(uploadFilePath);
}
}
);
//option2 upload_image.uploadFile(uploadFilePath);
deleteImageFromGallery(delete_image_id + "");
}
}
).start();
}
Hey i tried above code to upload image onto server.it runs well if i use the option 2 mentioned on the code. but if i put the code on the option 2.it gives me this error.
android.os.NetworkOnMainThreadException.
i think option 2 is better because it give a separate thread to complete the though it does not work properly

Related

Best practice to create a thread that runs every hour in Android?

So I'm attempting to create background task that needs to be run every hour in an Android app. Its a rather heavy task that takes around 5 - 10 minutes to finish, and right now it runs on the UI thread which of course isn't good, because it hangs the whole application. I've attempted the following in my MainActivity onCreate:
new Thread(new Runnable() {
private Handler HeavyTaskHandler = new Handler(Looper.getMainLooper());
public void run(){
final TextView updatedTxt = findViewById(R.id.txt);
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
updatedTxt.post(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
HeavyTaskHandler.postDelayed(this, HeavyTaskCycle);
}
}).start();
I have two issues with the above
It works fine the first time, and the task is performed in the background well without hanging the UI thread. However, after this first time and the next time(s) it is run, the UI thread hangs again when it is run. What am I missing?
Notice that before the HeavyTask() method is called i try to set a TextViews text to "Performing cleanup.." .. This never shows, only the "Done.." which happens after the HeavyTask() method is done. How can i ensure that the message also appears before?
I ended up doing the following from MainActivity which doesn't hang the application
private void CreateCleanUpThread()
{
CleanUpThread = new Thread(new Runnable() {
public void run(){
try {
while(true) {
performingCleanup = true;
final TextView updatedTxt = findViewById(R.id.updated_txt);
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Performing database history cleanup..");
}
});
HeavyTask(); // <-- This method runs for 5 - 10 minutes
runOnUiThread(new Runnable() {
#Override
public void run() {
updatedTxt.setText("Done..");
}
});
performingCleanup = false;
Thread.sleep(CleanUpCycle); // 1 hour wait time
}
} catch(Exception ex) {
System.out.println("Error in CreateCleanUpThread : " + ex.getMessage());
}
}
});
}
// onCreate in MainActivity
...
CleanUpThread.start();
Certainly not the best way, but it works and will do for now. Should be moved to a service instead i think.

Display message on non-stop thread

Following code is within an android activity class.
The project required a non-stop thread when apps is active and stop when apps is inActive/closed.
I predicted to see a non-stop "Hello World" message display in logCat.However I only saw one-times Hello World messgae .
What wrong of my code,so that I able to see a non-stop "Hello World"
Hope someone advice. Thanks
#Override
protected void onStart(){
super.onStart();
Log.e("onStart","beforeStart");
new HttpRequestTask().execute();
Log.e("onStart","Start");
this.pickButtonThread();
}
private void pickButtonThread(){
new Thread() {
#Override
public void run() {
try {
// code runs in a thread
PickerItemActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// code runs in a UI(main) thread
//isPickButtonEnableDisable();
//new HttpRequestTask().execute();
Log.e("pickButtonThread", "Hello World");
}
});
} catch (final Exception ex) {
}
}
}.start();
}
That's because you don't have any loop inside your run() method, thus it's run just once and it exits. However, declaring an endless loop is not considered a good idea as Android OS might kill it if there's lack of memory.
You could use a Handler using the .postDelayed() method to post messages every X seconds.
private Handler mHandler = new Handler();
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
Log.e("pickButtonThread", "Hello World");
mHandler.postDelayed(this, 1000); // Every second
}
};

Is there an Android equivalent to ASP.NET's DoEvents()?

I have an Android app where I would like to display a "Processing..." message at the start of quite a bit of heavy duty number crunching, then display "Finished" when the processing is completed. I try something like this:
TextView T = (TextView)findViewById(R.id.TheStatusView);
T.setText("Running");
T.invalidate();
// lots of number crunching
T.setText("Completed");
As some of you might have guessed by now, the "Running" message never appears, since the application is too busy with the number crunching to get around to redrawing the TextView.
In ASP.NET, I would do something like:
T.Text = "Running";
T.Refresh();
Application.DoEvents();
and the text would be refreshed.
Is there an equivalent in Android, or am I pretty much stuck?
For those of you who are playing at home and looking to do the same thing, here's what I did:
TextView T = (TextView)findViewById(R.id.statusTextView);
new Thread(new Runnable() {
public void run() {
T.post(new Runnable() {
public void run() {
T.setText("Processing Part 1");
}
});
DoTheHardcoreProcessing_Part1();
T.post(new Runnable() {
public void run() {
T.setText("Processing Part 2");
}
});
DoTheHardcoreProcessing_Part2();
T.post(new Runnable() {
public void run() {
T.setText("Finished");
}
});
}
}).start();
This will, in order:
(1) display "Processing Part 1"
(2) execute the code in DoTheHardcoreProcessing_Part1()
(3) display "Processing Part 2"
(4) execute the code in DoTheHardcoreProcessing_Part2()
(5) display "Finished"

Why I've got a mistake? android ProgressDialog+Thread

So, I have a code:
((Button) findViewById(R.id.run)).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
progDialog = ProgressDialog.show(WaggActivity.this,
"", "Loading...", true, true);
new Thread(new Runnable() {
public void run() {
try {
urlTxt.setText(findUrl(String.valueOf(search.getText())));
} catch (Exception e) {
Log.e("MainActivity", e.getMessage());
}
progDialog.dismiss();
}
}).start();
I cannot find a mistake. :(
Error is: Only the original thread created a view hierarchy can touch its vews.
In Android you have a UI-Thread, in which is created by your activity. This is the only thread in which you can modify the Views, which in your case is the ProgressDialog.
So you can't modify it from other threads, you must call it from within your Ui-thread.
You should call : Activity.runOnUiThread(Runnable)
; As explained here.
Isn't the error message quiet clear? Only the main thread may access the Views.
You are accessing urlTxt in another, custom thread.
To solve this issue, use the following snippet
urlTxt.post(new Runnable() {
public void run() {
urlTxt.setText(findUrl(String.valueOf(search.getText())));
}
});

Is this the best way to show content?

I'm relatively new in Android's world and the UI/Thread model is still confusing.
Here is what I am trying to do:
Load data from the web
Handle them
Show them
Show an AlertDialog if there is a problem
I'm currently doing like this, but I'm not sure that using many thread like that is the best way to do it.
Inside the onCreate()
final ProgressDialog pd = ProgressDialog.show(this, "", loadingText, true);
final AlertDialog.Builder b = new AlertDialog.Builder(this);
new Thread(new Runnable() {
#Override
public void run() {
try {
loadResorts();
} catch (ResortsRetrievalException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
b.setMessage(R.string.resorts_retrieval_error)
.show();
}
});
}
pd.dismiss();
}
}).start();
And my loadResorts method finishes with
final BaseAdapter a = new ResortAdapter(this, R.layout.resort_item, resorts);
runOnUiThread(new Runnable() {
#Override
public void run() {
resortsList.setAdapter(a);
}
});
I have one Thread and two calls of runOnUiThread for that. I feel that there could be a better solution without having to deal with these threads. Am I right?
Thanks
Use AsyncTask - it was created for this kind of scenarios: running a background task or (long) process, while still updating the UI in correct way (on EDT).

Categories

Resources