Getting data after the page loads works inconsistently - java

I'm attempting to make a menu that resizes to fit each device size. I have the buttons scaled, and the text will now correctly autofit into the buttons, but some text is longer than others. To accommodate this, I attempted to get the textSize of the largest text item and set the other text sizes to it with:
private class myAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(final Void... params) {
return null;
}
#Override
protected void onPostExecute(final Void result) {
super.onPostExecute(result);
about.setTextSize(contact.getEndTextSize());
hours.setTextSize(contact.getEndTextSize());
shop.setTextSize(contact.getEndTextSize());
}
}
The issue is that this will only work part of the time. I can navigate to one page multiple times and it will either work or won't.
My understanding is that onPostExecute is called when the background computation has finished. Is the issue that this timing doesn't necessarily coincide with when the page finishes rendering? Is there a better way to approach getting the textSize?

Related

Can I show animation until my Activity loads?

I was wondering if I can display some kind of animation until my activity loads. Because when I start my app , it takes about 5 seconds to see the Activity. Until it loads, a white screen is displayed (refer to the image below).
Can I do that ?
And if I can , how it should be done ?
Thanks you in advance.
Have a great day.
if you are downloading some data or u got ridiculusly large listview - you got other problems....
downloading data: reduce amout of data that is needed for app to work
listview - user freaking recyclerview
and if this is a legit problem - then you need some sort of listener(that indicates whenever job is complete) like Thread.join() and whenever that listener activates - it should go to another intent and kill last one (to kill you need to use finish();)
Try to use ProgressDialog in AsyncTask
new YourFragment.YourAsyncTask().execute();
Use this library sweet-alert-dialog for more animation Loading
class YourAsyncTask extends AsyncTask<Void, Void, Void> {
SweetAlertDialog pDialog;
#Override
protected void onPreExecute() {
//show your dialog here
super.onPreExecute();
pDialog = new SweetAlertDialog(getContext(), SweetAlertDialog.PROGRESS_TYPE);
pDialog.getProgressHelper().setBarColor(Color.parseColor("#fdc80b"));
pDialog.setTitleText("Loading...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Void result) {
//hide your dialog here
super.onPostExecute(result);
pDialog.dismissWithAnimation();
}
}
}
}

Android Thread explanation?

Sorry everyone this has been asked a few times but I just do not understand any of the answers because most are about timed UI updates. So I have a backgroundTasks thread that is called when my app first starts(Does network connections so..I think that's how you do it?)
public class MainActivity extends ActionBarActivity {
String data[][];
int arrayPosition = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
runBackgroundTask();
}
Here is my thread..
public void runBackgroundTask(){
new Thread(new Runnable() {
public void run() {
data = pullSchedule(data);
updateUI(data,arrayPosition);
}
}).start();
}
All it does is call a method pullSchedule which updates a 2D array with a webcrawler. So my problem comes when I call the updateUI method which is also used by two buttons to cycle through the array data which work perfectly fine. It's just when the thread first runs if I try to update the UI I get an error.
public void upDateUI(String data[][], int arrayPosition){
TextView gameTime =(TextView)findViewById(R.id.txtDate);
//more but deleted to save space :)
}
I have researched why I cannot update the UI from the background thread but I don't understand how to fix this? I thought about putting that entire method into the runOnUiThread(new Runnable()but then I believe my data and arrayPosition have to be declared final because of an inner class..First Android app just lost. Thanks for any help.
you can use asyntask for this from which you can update ui
public myAsyn extends AsyncTask<Void,Void,Void>
{
#Override
protected String doInBackground(Void... params) {
data = pullSchedule(data);
return null;
}
#Override
protected void onPostExecute(String result) {
updateUI(data,arrayPosition);
}
}
doInBackground runs on seperate thread whereas onPostExecute runs on Ui thread therefore you can update UI from there.
You are on the right track. The reason your app is crashing is because you are attempting to update a UI element off of the UI thread. To avoid this, you can either do as RichS suggested, and use an AsyncTask which will execute onPostExecute() on the UI thread, or surround your updateUI() call in your background thread with runOnUiThread(new Runnable() {....

Android Activity takes too long to show content

My Activity in onCreate() performs long computations that take some time.
In the same onCreate() I call setContentView() to set the appearance of the activity.
The point is that, since it takes a while to performs the above mentioned computations the screen of the Activity loads only after long time.
Please, any suggestion on how to avoid this?
I have tried to call setContentView() in onCreate() and start the computations in onResume(), but again the Activity screen is loaded only at the end.
There is no other way than to use e.g. an AsyncTask. The reason is that the actual rendering does not take place asynchronously; in other words, setContentView will only set some data but nothing will be displayed at that point in time.
AsyncTask, however, is not necessarily meant for "long" computations. But if your app relies on the result, and no other computations take place in parallel, it may still be the simplest way for you to achieve what you want. If not, you may have to use a Thread even.
Update Since everybody keeps bombarding the original poster with more use AsyncTask answers of various quality, I'd like to stress one more time that AsyncTask is intended for short operations (to quote the reference: a few seconds at the most) while the OP has given no indication on how long his computations really take. Also, an AsyncTask is a one-shot-only object which can only run once.
One more very important point to consider is the following. Android assigns AsyncTask a background task priority. This means that, besides the lower scheduling priority, the computations in AsyncTask will take ten times as long as if they were performed in the foreground, because Android runs all tasks which have background priority with an artificial limit of 10% CPU cycles. However, AsyncTasks can be lifted out of this group by raising its priority "just a little bit". For an AsyncTask, it would be done like so:
public R doInBackground(I... is) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
Process.THREAD_PRIORITY_MORE_FAVORABLE);
...
}
You have to implement AsyncTask
public class AsyncTaskActivity extends Activity implements OnClickListener {
Button btn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button1);.
//because we implement OnClickListener we only have to pass "this" (much easier)
btn.setOnClickListener(this);
}
public void onClick(View view){
//detect the view that was "clicked"
switch(view.getId())
{
case R.id.button1:
new LongOperation().execute("");
break;
}
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for(int i=0;i<5;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = (TextView) findViewById(R.id.output);
txt.setText("Executed"); // txt.setText(result);
//might want to change "executed" for the returned string passed into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
If all computations take long time to execute, your UI is 'locked' and not updated.
You need to do all long work in an AsyncTask
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
call setContentView(layoutID) in onCreate method before you start initializing views, create a AsyncTask and start AsyncTask thread after you called setContentView in onCreate method only. Something like given below
onCreate(....){
--
--
setContentView(layoutID);
---
--
new asynchTask(); // load your ui in AsyncTask by creating an inner class in your activity by extending AsyncTask class
}
here is a tutorial of how to implement AsyncTask

AsyncTask is still running after onPostExecute() in debug window

I have a program that creates an android application.
The main class of this program uses Async Tasks to connect, then request data. Both connect and request data are started via a button and a progress bar is displayed in both cases.
When I start the Async Task for connect, the program runs through the methods onPreExecute(), doInBackground(), onProgressUpdate() and onPostExecute(), which is as expected.
However after onPostExecute(), when I look in the debugger window, AsyncTask is still running and continues to run. When I then request data, a new AsyncTask is created and I have two running.
How do I terminate the first AsyncTask (and indeed the second once it has finished) as after using the program for a while I end up with around 20 AsyncTask threads still running!
I've included my code below:
private ProgressDialog connectionDialog;
private ProgressDialog requestDataDialog;
private ProgressDialog usingDialog;
private int currentDialog;
public void connectClick(View view) //When the connect button is clicked
{
currentDialog = 1;
new PerformTask().execute();
}
private class PerformTask extends AsyncTask<Void, Integer, Integer>
{
protected void onPreExecute()
{
showDialog(currentDialog);
}
protected Integer doInBackground(Void... voi)
{
int total = 0;
//Perform the task required
publishProgress(total);
return total;
}
protected void onProgressUpdate(Integer... progress)
{
usingDialog.setProgress(progress[0]);
}
protected void onPostExecute(Integer result)
{
removeDialog(currentDialog);
}
}
protected Dialog onCreateDialog(int id)
{
//Setup the dialogs
}
public void requestDownloadClick(View view)
{
currentDialog = 2;
new PerformTask().execute();
}
Just for completeness and so I can accept the question, here is the answer, given by grv_9098, found at stackoverflow.com/a/3077508/1514187 :
AsyncTask manages a thread pool, created with ThreadPoolExecutor. It will have from 5 to 128 threads. If there are more than 5 threads, those extra threads will stick around for at most 10 seconds before being removed. (note: these figures are for the presently-visible open source code and vary by Android release).
Leave the AsyncTask threads alone, please.

Update View at runtime in Android

The example is pretty straightforward: i want to let the user know about what the app is doing by just showing a text (canvas.drawText()). Then, my first message appears, but not the other ones. I mean, i have a "setText" method but it doesn't updates.
onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(splash); // splash is the view class
loadResources();
splash.setText("this");
boundWebService();
splash.setText("that"):
etc();
splash.setText("so on");
}
The view's text drawing works by doing just a drawText in onDraw();, so setText changes the text but doesn't show it.
Someone recommended me replacing the view with a SurfaceView, but it would be alot of trouble for just a couple of updates, SO... how the heck can i update the view dinamically at runtime?
It should be quite simple, just showing a text for say 2 seconds and then the main thread doing his stuff and then updating the text...
Thanks!
Update:
I tried implementing handler.onPost(), but is the same story all over again. Let me put you the code:
public class ThreadViewTestActivity extends Activity {
Thread t;
Splash splash;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
splash = new Splash(this);
t = new Thread(splash);
t.start();
splash.setTextow("OA");
try { Thread.sleep(4000); } catch (InterruptedException e) { }
splash.setTextow("LALA");
}
}
And:
public class Splash implements Runnable {
Activity activity;
final Handler myHandler = new Handler();
public Splash(Activity activity) {
this.activity=activity;
}
#Override
public void run() {
// TODO Auto-generated method stub
}
public synchronized void setTextow(final String textow) {
// Wrap DownloadTask into another Runnable to track the statistics
myHandler.post(new Runnable() {
#Override
public void run() {
TextView t = (TextView)activity.findViewById(R.id.testo);
t.setText(textow);
t.invalidate();
}
});
}
}
Although splash is in other thread, i put a sleep on the main thread, i use the handler to manage UI and everything, it doesn't changes a thing, it only shows the last update.
I haven't hit this yet, but I think the usual pattern is to do lengthy initialization in a background thread, and use Handler.post() to update the UI. See http://developer.android.com/reference/android/widget/ProgressBar.html for a different, but possibly related, example.
Also see this answer, especially the first paragraph:
The problem is most likely that you
are running the splash screen (some
sort of Dialog such as ProgressDialog
I assume) in the same thread as all
the work being done. This will keep
the view of the splash screen from
being updated, which can keep it from
even getting displayed to the screen.
You need to display the splash screen,
kick off an instance of AsyncTask to
go download all your data, then hide
the splash screen once the task is
complete.
Update (based on your update and your comment): You are not supposed to update the UI in any thread except the one where your Activity is created. Why is it impossible for you to load your resources in a background thread?
First: onCreate is executed on main UI thread of application so no UI updates until you leave it. Basically you need one thread to execute long running tasks and some mechanism to push updates into the UI.
Most usual approach is to extend AsyncTask see this link for further info
i suppose that your view is an extended view and you call onDraw for drawing the view, so, maybe the view isnĀ“t 'refresh' their state, so try this
onCreate(Bundle bundle) {
setContentView(splash); // splash is the view class
loadResources();
splash.setText("this");
splash.invalidate();
boundWebService();
splash.setText("that"):
splash.invalidate();
etc();
splash.setText("so on");
splash.invalidate();
}

Categories