Android App is not loading in AVD properly - android

my app is just at starting mode but does not load completely
the Logcat Message is :
"Skipped 33 frames! The application may be doing too much work on its main thread."
please help me ..

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("in on create", "before thread");
new handler().start();
}
private class handler extends Thread {
#Override
public synchronized void start() {
super.start();
Log.d("in handler ", "inside start");
}
}
}

If you really think that is doing all of the work on UI Thread. then just do create a Thread object and make your function calls in its run()
Thread t=new Thread();
t.start();
public void run(){
makeYourFunctionCallHere();
}
or you can use ASysncTask if doing some network operation.

Use Async Task to run the tasks in background.
Here is a example :
http://android-am.blogspot.in/2012/10/async-task-with-progress-dialog-in.html

Please let me know if you are doing some network operation, Bitmap downloading and setting on ImageViews iteratively. This consumes much memory to be done So this kind of issues raised.
In case of Bitmap downloading and setting to imageView you should resize images as per imageView (eg. list image-icons in ListView).

Related

sleep in thread with while loop without sleep in UIThread

How can I make use of a delay in the while loop without also delaying the UIThread?
My while loop should update the UI everytime the app run through the loop but there should also be the possibility to interact with a button. The problem I have with my current version is that the app pauses when the while loop is started until the while loop is finished and then updates the UI. I want it to update the UI with every pass through.
Do you have any ideas, maybe also an alternative way that is more efficient?
This is my current version:
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Button;
import android.widget.ProgressBar;
import android.view.View.OnClickListener;
import android.widget.Toast;
import java.util.regex.Pattern;
public class ReaderFragment extends Fragment
{
ProgressBar progress_in_main_thread;
private int progressBarStatus = 0;
TextView main_text;
Pattern p = Pattern.compile(" ");
String[] splitted_text;
Button start_button;
Button pause_button;
public boolean paused;
int index = 0;
long wait = 1000;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
//Layout des Fragments verknuepfen
{
View ReaderFragmentView = inflater.inflate(R.layout.reader_fgmt, container, false);
progress_in_main_thread = (ProgressBar) ReaderFragmentView.findViewById(R.id.reader_progress);
progress_in_main_thread.setProgress(0);
progress_in_main_thread.setVisibility(progress_in_main_thread.VISIBLE);
main_text = (TextView) ReaderFragmentView.findViewById(R.id.center_view);
start_button = (Button) ReaderFragmentView.findViewById(R.id.go);
start_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
if(InputFragment.text.trim().length() == 0)
{
Toast.makeText(getActivity().getApplicationContext(), "Es wurde kein Text eingegeben!", Toast.LENGTH_SHORT).show();
}
else
{
paused = false;
splitted_text = p.split(InputFragment.text);
progress_in_main_thread.setMax(splitted_text.length-1);
mainThread();
}
}
});
pause_button = (Button) ReaderFragmentView.findViewById(R.id.pause);
pause_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View view)
{
paused = true;
}
});
return ReaderFragmentView;
}
private void mainThread()
{
new Thread(new Runnable()
{
#Override
public void run()
{
while(progressBarStatus < (splitted_text.length)-1)
{
progressBarStatus = index;
progress_in_main_thread.setProgress(progressBarStatus);
}
}
}).start();
getActivity().runOnUiThread(new Runnable()
{
public void run()
{
while(!paused)
{
main_text.setText(splitted_text[index]);
if(paused)
{
break;
}
else if(index == (splitted_text.length)-1)
{
Toast.makeText(getActivity().getApplicationContext(), "Ende", Toast.LENGTH_LONG).show();
break;
}
index++;
try
{
Thread.sleep(wait);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
});
}
}
Thank you all!
By definition, you cannot delay the UI thread without delaying the UI thread.
Fundamentally, you need to switch from a loop style of program to an event driven one, which in which the Android UI must be handled. Your program will not have a while loop - instead, the Android framework will call into your code to execute event functions, each of which must return as quickly as possible.
Android already does this out of the box to deliver user interaction events such as touches and button pushes, and lifecycle events. To add events for periodic evolution of your UI (what you were trying to do with the while loop and delay), you can create a Timer and have its TimerTask push some UI related work to do onto the UI Thread using RunOnUiThread; if what you need to do does not involve the UI, then you can just do it in the background thread where the TimerTask executes.
In your posted code, it looks like you might have attempted to create your own background thread which would run a loop with a sleep delay, and push work to the UI thread with RunOnUiThread; technically that is workable, but not really encouraged compared to the timer method. However, there are two problems with the way that you did it:
First, you named the launcher method for your background thread mainThread, which is a bit confusing as on Android the "main thread" and the "UI thread" are one and the same - it would be better to call it createBackgroundThread() or something.
Second, you have the while and sleep occurring within the code which it pushes to the UI thread for execution, which is unworkable. You will need to move the while loop and sleep out into the background thread and instead have it repeatedly use RunOnUiThread when you need to push onto the UI Thread small batches of work which can immediately complete, such as each actual visual update.
Also you may want to put some thought into if your implementation could end up creating multiple concurrent background threads as a result of repeated button pushes, or one of your threads it is still running when a significant Activity Lifecycle event occurs.

android - calling ui thread from worker thread

Hi I want to make Toast available to me no-matter-what and available from any thread whenever I like within my application. So to do this I extended the Activity class:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Toast;
public class MyActivity extends Activity{
private Handler mHandler;
#Override
public void onCreate(Bundle savedInstanceState) {
mHandler = new Handler();
super.onCreate(savedInstanceState);
}
private class ToastRunnable implements Runnable {
String mText;
public ToastRunnable(String text) {
mText = text;
}
public void run(){
Toast.makeText(getApplicationContext(), mText, Toast.LENGTH_SHORT).show();
}
}
public void doToast(String msg) {
mHandler.post(new ToastRunnable(msg));
}
}
so that all Activity classes in my app are now simply
public class AppMain extends MyActivity {
//blah
}
what I expected to be able to do (in a worker thread) was this:
try{
MyActivity me = (MyActivity) Looper.getMainLooper().getThread();
me.doToast("Hello World");
}
catch (Exception ex){
Log.e("oh dear", ex.getMessage());
}
and so long as the Activity was a "MyActivity" it should work - but the problem is ---> the Looper.getMainLooper().getThread(); isn't returning the MyActivity to me and it's making me cry - what am I doing wrong?
: EDIT :
some background to explain "why" I am stuck with this type of implmentation.
I need to be able to confirm to the user that a "HTTP POST" event has been a success. Now. If the User clicks "OK" on the UI Form it MAY or MAY NOT have internet at that time.. If it has Internet - all well and good - it posts the form via HTTP POST all well and good.. but if there is NO Internet most (99.999% of Android apps lame /pathetic / mewling at this, and basically offer the user no plan "b" assuming that at all times the internet is there - when it is NOT)
My App will not "go lame (as I call it)" - it does have a plan "b" instead it "Queues" the post event and retries every x minutes.. now this is a silent thread in the background.. I have plenty of user interaction all over the app I don't know where the user will "be" but eventually when the HTTP POST that queue/retries/queue/retries returns "! Success! " I want to Toast that as a message to the user (EG: "your form was sent")
What's wrong with runOnUiThread?
http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
}
});
use below code. create activity object which contains your activity instance..
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity.getApplicationContext(),"Toast text",Toast.LENGTH_SHORT).show();
}
);
This will allow you to display the message without needing to rely on the context to launch the toast, only to reference when displaying the message itself.
runOnUiThread was not working from an OpenGL View thread and this was the solution. Hope it helps.
private Handler handler = new Handler();
handler.post(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello, world!", Toast.LENGTH_SHORT).show();
}
});
You can't just cast the result of getThread() to an instance of your MyActivity base class. getThread() returns a Thread which has nothing to do with Activity.
There's no great -- read: clean -- way of doing what you want to do. At some point, your "worker thread" abstraction will have to have a reference to something that can create a Toast for you. Saving off some static variable containing a reference to your Activity subclass simply to be able to shortcut Toast creation is a recipe for memory leaks and pain.
Why don't you send an intent that is captured by a BroadCastReceiver, then the broadcast receiver can create a notification in the notification tray. It's not a toast, but its a way to inform the user that his post has been successful.
If it's within your own activity, why can't you just call doToast()?
if you have the context with you, you can call the ui thread like this from non activity class.
((Activity)context).runOnUiThread(new Runnable() {
public void run() {
// things need to work on ui thread
}
});

Thread communication within the activity

I have an activity class as below.
public class LoginActivity extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (ImageView) findViewById(R.id.button1);
button1.setOnClickListener(this);
}
#Override
public void onClick(View v) {
loader = (ProgressBar) findViewById(R.id.loader);
Thread processThread = new Thread(loaderThread);
loader.setVisibility(View.VISIBLE);
processThread.start();
try {
Thread.currentThread().join();
Log.i("Activity","gone past join()");
loader.setVisibility(View.INVISIBLE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Runnable loaderThread = new Runnable() {
public void run() {
ServiceCaller serviceCaller = new ServiceCaller();
boolean status = serviceCaller.checkProcess(url);
}
};
}
Further Question [EDITED]
Here is the scenario. The main activity class creates a thread on a click. The then created thread fetches some data from the server. It is a time consuming task. So a progress bar is displayed on the UI. Currently I am using AsyncTask (not shown here) to accomplish server data retrieval. But the real challenge is wait for the background task to complete and get the value from it. What I am looking for is:
wait until server calls are made and get the results. Meanwhile show the progress bar.
Any thoughts? Apologies in case I confuse you.
Thanks in advance!
You must have a look at AsyncTask
http://developer.android.com/reference/android/os/AsyncTask.html
http://www.vogella.com/articles/AndroidPerformance/article.html
and you can show the ProgressBar in onPreExecute()
do the task in doInBackground()
and hide the ProgressBar in onPostExecute()
Join method blocks the current thread. In your case Onclick method is called in UI thread, so all UI operations are blocked. It is never a good idea to block Ui thread.
So you probably should use either a Handler or Asynctask to keep updating Progressbar

Creating and killing threads in Android

I have an application that creates a thread to do some work. When the work is done I kill the thread. Problem is that every time I do kill the thread, the heap seems to have increased by 10k? To test further I did the following in a 1ms handler.
TestThread new_thread = new TestThread();
new_thread = null;
Every time I run this I see the heap increase under DDMS. The TestThread does nothing. It has no code. Its just an empty thread.
import android.util.Log;
public class TestThread extends Thread {
public TestThread () {
Log.d("TESTTHREAD","Constructed");
}
public void run() {
Log.d("TESTHREAD","Run");
}
}
Any idea why this is?
The myThread.stop() method is deprecated because it might leave the application in an
unpredictable state. Instead, use the following when needed, such as in the onStop()
method of the parent component:
//use to stop the thread myThread
if(myThread != null) {
Thread dummy = myThread;
myThread = null;
dummy.interrupt();
}

Why does Handler::postDelay make UI frozen

I have this code. I don't know why postDelay make UI frozen in this case. I want the Runnable will run after 100 miliseconds deley and run in 4000 miliseconds.
package com.delaythread;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
public class MyNeedActivity extends Activity implements OnClickListener {
private ProgressBar progressBar;
private final Handler handler = new Handler() {
#Override
public void handleMessage(final Message msg) {
super.handleMessage(msg);
progressBar.setVisibility(ProgressBar.INVISIBLE);
}
};
#Override
public void onClick(final View v) {
if(v.getId() == R.id.button1) {
/* This call doesn't make ProgressBar frozen.
final Thread t = new Thread(new MyRunnable());
t.start();
progressBar.setVisibility(ProgressBar.VISIBLE);
*/
// This makes ProgressBar frozen in 4000 miliseconds.
final boolean b = handler.postDelayed(new MyRunnable(), 100);
if(b) {
progressBar.setVisibility(ProgressBar.VISIBLE);
}
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button)findViewById(R.id.button1)).setOnClickListener(this);
progressBar = (ProgressBar)findViewById(R.id.progressBar1);
}
private class MyRunnable implements Runnable {
#Override
public void run() {
sleep();
}
private void sleep() {
try {
Thread.sleep(4000);
handler.sendEmptyMessage(0);
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
}
}
Update: Actually what I want is AsyncTask executes after a delay time, so I do as this answer Java/android how to start an AsyncTask after 3 seconds of delay?. He said I should use Handler and Runnable.
The following should suit your need according to the post
private final Handler handler = new Handler() {
#Override
public void handleMessage(final Message msg) {
super.handleMessage(msg);
//start Asyntask here. progress show/hide should be done in asynctaswk itself.
}
};
#Override
public void onClick(final View v) {
if(v.getId() == R.id.button1) {
final boolean b = handler.postDelayed(new MyRunnable() , 1000);
}
}
private class MyRunnable implements Runnable {
#Override
public void run() {
handler.sendmessage(0);
}
}
}
You probably want to run your MyRunnable on other thread than main UI one, so you need to start a regular thread for this, like
new Thread(new MyRunnable()).start();
instead of using Handler for this, which queues your runnable to be executed on main UI thread.
BTW, for this purpose Timer with TimerTask would suit better.
The Android Reference for the class Handler points out:
"[...] When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it [...]"
So your Handler, created on instantiation of the Activity, should be running on the UI thread causing it to block when your Runnable is executed.
Try creating a new Thread class in which your Handler is instantiated. Then pass the Runnable to it from your onClick() method. To pass messages back (such as updating the progress bar) you can use another Handler that is running on the UI thread.
You could also save yourself a lot of pain by taking a look at the AsyncTask class.
PS:
Delaying the execution could be done in the AsyncTaskdoInBackground() via a Thread.sleep(100) call. To delay execution on UI thread level you could do the same in AsyncTask.onPreExecute().
As far as I understand it you ask your MyRunnable to run on the GUI thread (of which there is only one); but the only this it does is sleep, effectively causing the GUI thread to freeze waiting for it.
You shouldn't do complicated calcultaions (or, sleep) in the GUI thread.
You may want to read the documentation on threads and the UI thread for a more elaborate description.
Your progress bar isn't updating because you aren't updating it! Try using an AsyncTask, (it runs on a different thread but allows you to update UI elements) and setting the state of the progress bar from within the onProgress method in the Async task.
OR
Just follow this example on the Android Progress Bar page
Try this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Code to be executed after desired seconds
}
}, seconds*1000);
This would freeze the UI for given number of seconds and the execute the code inside the run()

Categories

Resources