Thread is not working. the application close unexpexted. - android

i am trying to show the progress dialog in my program when press the refresh button but the application close unexpexted with error in debugger that the thread which one is created ui hierachy can only touch it.
public class MainActivity extends Activity {
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.refreshView();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void refreshView(){
ImageView img = (ImageView) findViewById(R.id.imageView1);
Bitmap bm = null;
InputStream is = null;
BufferedInputStream bis = null;
try
{
URLConnection conn = new URL("http://technomoot.edu.pk/$Common/Image/Content/ciit_logo.jpg").openConnection();
conn.connect();
is = conn.getInputStream();
bis = new BufferedInputStream(is, 8192);
bm = BitmapFactory.decodeStream(bis);
}
catch (Exception e)
{
e.printStackTrace();
}
finally {
if (bis != null)
{
try
{
bis.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
if (is != null)
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
img.setImageBitmap(bm);
}
public void onRefresh(View view) {
final ProgressDialog dialog = ProgressDialog.show(this,"Loading","Loading the image of the Day");
Thread th = new Thread(){
public void run(){
refreshView();
handler.post(new Runnable(){
public void run(){
dialog.dismiss();
}
}
);
}
};th.start();
}
}

You can't manipulate with UI from worker Thread! It's prohibited! If you want to update UI just use
runOnUiThread()
AsyncTask
So try it like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
// do your work.
}
});
AsyncTask is more complex, also generic-type that provides some benefits like type control etc. You can look at example here:
Android application (performance and more) analysis tools -
Tutorial

You are calling a ui operation from a non ui thread, you can Use runOnUiThread..
or better use AsynchTask
public YourTask extends AsyncTask<Object,Object,Object>{ //change Object to required type
ProgressDialog dialog;
Context context;
public YourTask(Context context){
this.context=context;
}
protected void onPreExecute(Object o){
dialog = ProgressDialog.show(this,"Loading","Loading the image of the Day");
}
protected void doInBackground(Object o){
refreshView();
}
protected void onPostExecute(Object o){
img.setImageBitmap(bm);
dialog.dismiss();
}
}

Related

Create thread to run long-work but not responses

thread = new Thread(new Runnable() {
#Override
public void run() {
synchronized (datahandler) {
while (true) {
try {
if (datahandler.getCount() > 0) {
commitData();
}
datahandler.wait();
} catch (InterruptedException e) {
e.printStackTrace();
Log.e("Service", e.toString());
}
}
}
}
});
thread.start();
Commitdata to connect and commit data form datahandler to server. But I dont kow why it shows not respone dialog. If I do not close it, it continouns to commit. Why UI is influenced when I commit data in other thread
public class ThreadsLifecycleActivity extends Activity {
// Static so that the thread access the latest attribute
private static ProgressDialog dialog;
private static Bitmap downloadBitmap;
private static Handler handler;
private ImageView imageView;
private Thread downloadThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// create a handler to update the UI
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
imageView.setImageBitmap(downloadBitmap);
dialog.dismiss();
}
};
// get the latest imageView after restart of the application
imageView = (ImageView) findViewById(R.id.imageView1);
Context context = imageView.getContext();
System.out.println(context);
// Did we already download the image?
if (downloadBitmap != null) {
imageView.setImageBitmap(downloadBitmap);
}
// check if the thread is already running
downloadThread = (Thread) getLastNonConfigurationInstance();
if (downloadThread != null && downloadThread.isAlive()) {
dialog = ProgressDialog.show(this, "Download", "downloading");
}
}
public void downloadPicture(View view) {
dialog = ProgressDialog.show(this, "Download", "downloading");
downloadThread = new MyThread();
downloadThread.start();
}
// save the thread
#Override
public Object onRetainNonConfigurationInstance() {
return downloadThread;
}
// dismiss dialog if activity is destroyed
#Override
protected void onDestroy() {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
dialog = null;
}
super.onDestroy();
}
static public class MyThread extends Thread {
#Override
public void run() {
try {
// Simulate a slow network
try {
new Thread().sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
downloadBitmap = downloadBitmap("http://www.devoxx.com/download/attachments/4751369/DV11");
// Updates the user interface
handler.sendEmptyMessage(0);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
}
//==========================
You can sea in code that handlers are used to post message on GUI thread. further you can read about it over here
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
Also Read This http://android-developers.blogspot.de/2010/07/multithreading-for-performance.html

My Thread is not working

I am trying to combine two simple application that I found on the net.I have a thread and after 5 seconds my sensor lists should be displayed with a Toast message.But Nothing happens ..Thread is not working I think I messed up everything.Could you please help. I would really appriciate
public class MainActivity extends Activity{
List<String>sName=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Loadingg", Toast.LENGTH_LONG).show();
Thread thr=new Thread(){
#Override
public void run (){
try {
sleep(5000);
StringBuilder message=DisplaySensors();
Toast.makeText(getApplicationContext(),message, Toast.LENGTH_LONG).show();
} catch (Exception e) {
// TODO: handle exception
}
}
private StringBuilder DisplaySensors() {
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor>sList=sm.getSensorList(Sensor.TYPE_ALL);
StringBuilder sb=new StringBuilder();
for (int i = 0; i <sList.size(); i++) {
sb.append(((Sensor)sList.get(i)).getName()).append("\n");
}
return sb;
}
};
thr.start();
}
All UI operations have to run on Main UI Thread. So if you want to show a toast message, this shouldn't done in a seperated Thread. In this case, toast message has to be in runOnUiThread() block as seen below.
public class MainActivity extends Activity{
List<String>sName=new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "Loadingg", Toast.LENGTH_LONG).show();
Thread thr=new Thread(){
#Override
public void run (){
try {
sleep(5000);
StringBuilder message=DisplaySensors();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message, Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
private StringBuilder DisplaySensors() {
SensorManager sm=(SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor>sList=sm.getSensorList(Sensor.TYPE_ALL);
StringBuilder sb=new StringBuilder();
for (int i = 0; i <sList.size(); i++) {
sb.append(((Sensor)sList.get(i)).getName()).append("\n");
}
return sb;
}
};
thr.start();
}
You should not use the Toast in a Thread. Use runOnUiThread instead:
See this
#Override
public void run (){
try {
Thread.sleep(5000);
StringBuilder message=DisplaySensors();
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),message,Toast.LENGTH_LONG).show();
}
});
} catch (Exception e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

GUI not displaying all packets received

I below is my code for receiving Multicast Wifi Data on android. I am using runnables like below to update the GUI but i found thatsome packets are missing. I am using this code to receive count down message but the count down is not continious. I dont know whether packets are lost due to the style of GUI updating or due to some other problem. request you all to give suggestions.
package com.example.cdttiming;
public class MainActivity extends Activity
{
EditText time;
String s;
Button button;
InetAddress ia = null;
byte[] bmessage = new byte[1500];
DatagramPacket dp = new DatagramPacket(bmessage, bmessage.length);
MulticastSocket ms = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
time = (EditText) findViewById(R.id.et_time);
try
{
WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE);
//wm.setWifiEnabled(true);
WifiManager.MulticastLock multicastLock = wm.createMulticastLock("multicastLock");
multicastLock.setReferenceCounted(true);
multicastLock.acquire();
ia = InetAddress.getByName("226.1.1.1");
try {
ms = new MulticastSocket(4321);
} catch (IOException e) {
e.printStackTrace();
}
try {
ms.joinGroup(ia);
} catch (IOException e) {
e.printStackTrace();
}
ms.setReuseAddress(true);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void startProgress(View view) {
Runnable runnable = new Runnable() {
#Override
public void run() {
while(true)
{
try
{
ms.receive(dp);
s = new String(dp.getData(),0,dp.getLength());
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
time.post(new Runnable() {
#Override
public void run() {
time.setText(s);
}
});
} // while
}
};
new Thread(runnable).start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
You have no access to main UI thread. That is why you can't set text to UI view element.
There are few methods to get access to UI thread
1) use Activity.runOnUiThread()
this.runOnUiThread( new Runnable() { #Override
public void run() {
time.setText(s);
} })
2) I suppose best in your case use Handler object wich is a bridge between your worker threads and main UI thread
private Handler handler = new Handler(){
#Override
public void handleMessage(Message message) {
switch (message.what) {
case SET_TEXT:{
time.setText(s);
}break;
}
...
handler.sendEmptyMessage(SET_TEXT);

Android Task AsyncTask issue with postExec

the Problem I am having is that the PostExecute is not firing.
I see the log tag for background but P.E. never fires.
I am invoking this task from a timer like this:
findViewById(R.id.buttonstart).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
openFile("FeedTimerTask.html");
Timer t = new Timer("FeedTimerTask", true);
timerTask = new FeedTimerTask();
t.schedule(timerTask, 2000, 20000);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Runnable runme = new Runnable() {
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
class FeedTimerTask extends TimerTask{
#Override
public void run() {
try{Looper.prepare();}catch(Exception e){};
runme.run();
}
}
Here is the main task itself from inside the dataprovider class invoked with "provider.refreshNoCache();" above:
// threaded rteftesh tasks
#SuppressWarnings("rawtypes")
public class RefreshTask extends SupportAsyncTask {
private int errorcodecode = 0;
private ProgressDialog dialog=null;
private Exception mainExeption=null;
protected String waitMessage = "Laddar ner information..";
private boolean useCache;
public RefreshTask(boolean useCache) {
this.useCache = useCache;
}
public void onPreExecute() {
data = null;
if (showSpinnerOnRefresh){
dialog = ProgressDialog.show(context, "", waitMessage , true);
dialog.show();
}
}
protected Object doInBackground(Object... params) {
errorcodecode = 1;
try {
invokeFeedRead();
Log.e("DataProvider", "Bkgtask...");
errorcodecode = 0;
} catch (BrJSONException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 1;
} catch (IOException e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 2;
} catch (Exception e) {
Log.e("[ERROR]","PROVIDER "+e.getMessage());
mainExeption = e;
errorcodecode = 3;
}
if (errorcodecode==0){
}
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.e("DataProvider", "Cancelled...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
BrAlert.Show(context, "Obs", BrAppConfig.ServerError+" (timeout)", 0);
onError_IO(new IOException("Timeout!"));
errorcodecode=2;
}
#Override
protected void onPostExecute(Object result) {
// super.onPostExecute(result);
Log.e("DataProvider", "PostExec...");
if (dialog != null)
try{dialog.dismiss();}catch(Exception e){}
switch (errorcodecode) {
case 0:
onFeedLoaded();
cacheAge = System.currentTimeMillis();
break;
case 1:
onError_DataFormat(mainExeption);
break;
case 2:
onError_IO(mainExeption);
break;
default:
onError_GeneralExeption(mainExeption);
}
}
}
Your task is cancelled even before it reached onPostExecte method. If the task is cancelled before it reaches onPostExecute Method. It will not trigger onPostExecute but trigger onCancelled Method. Please provide enough time to finish the task.
I found out the problem in the end. It was to do with the scope.
I needed a handler to invoke the other thread.
Here is the solution for others may find helpful:
in on create:
tickHandler = new Handler();
tickTimer = new Timer();
tickTimer.schedule(new FeedTimerTask(),
0,
50000); //FPS
The handler class.
class FeedTimerTask extends TimerTask{
private Runnable runable;
public FeedTimerTask(){
super();
runable = new Runnable(){
#Override
public void run() {
timestart = Calendar.getInstance().getTimeInMillis();
provider.refreshNoCache();
}
};
}
#Override
public void run() {
tickHandler.post(runable);
}
}

Android: Progress Bar while loading

In Android development, I am loading a drawable from a url with this code:
public Drawable getImageFromURL(String sURL) {
Object content = null;
try {
URL url = new URL(sURL);
content = url.getContent();
} catch (Exception ex) {
ex.printStackTrace();
}
InputStream is = (InputStream) content;
return Drawable.createFromStream(is, "src");
}
But I want to display this ProgressBar while it loads the drawable:
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
progressBar = ProgressDialog.show(TabMenu.this, getString(R.string.name), getString(R.string.specials));
progressBar.setIcon(R.drawable.icon_template);
How do I do that? I call getImageFromURL() in the onCreate() methode of the Activity.
Thanks for your help!
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// do something
switch (msg.what){
case 1:
//ALL FUNCTION(S) -----------------------------
//-----------------------------------------------------
//-----------------------------------------------------
p_dialog.dismiss();
break;
// if error
case 0:
Toast.makeText(aktiviti.this, "Error", Toast.LENGTH_SHORT).show();
p_dialog.dismiss();
break;
}
}
};
ON CREATE ---------> <----------------
Button new_button = (Button) findViewById(R.id.new_button);
new_button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
p_dialog = ProgressDialog.show((activity_name).this, "", "Loading Image...");
new Thread(new Runnable() {
public void run() {
processThread();
}}).start();
}
private void processThread() {
try{
handler.sendEmptyMessage(1);
}
catch (Exception e){
handler.sendEmptyMessage(0);
}
}
}
});
Good Luck!
You need to download the image in a new thread. You can use a AsyncTask for simplicity as in this example which implements also the progressbar

Categories

Resources