I am using Glide v4 and it is not always can get bitmap from Url. Sometimes it works and Sometimes it does not work and throw an exception. I don't know why. this is the Exception:java.lang.IllegalArgumentException: You must call this method on a background thread and this is my code:
try {
bitmap=Glide.with(mContext.getApplicationContext())
.asBitmap().load(icon).fitCenter()
.circleCrop().submit().get();
} catch (Exception e) {
bitmap= BitmapFactory.decodeResource(mContext.getResources(),
R.drawable.ic_default_user_image);
}
I am facing another problem with Glide, this is the issue I made on Glide Github : https://github.com/bumptech/glide/issues/3590
java.lang.IllegalArgumentException: You must call this method on a background thread
The exception is very clear . you can't run your code that load a img on the main thread(which is UI Thread). This link may solve ur problem.
The exception says - "You must call this method on a background thread", for example :
Thread mThread = new Thread(new Runnable() {
#Override
public void run() {
try {
//Put your code that you want to run in here
} catch (Exception e) {
e.printStackTrace();
}
}
});
mThread.start
Related
I am trying to review the concept of Handler. So I simply create a Thread to update a ProgressBar and see if it would throw an exception.
Here's my code
#Override
public void onResume() {
super.onResume();
new Thread(){
#Override
public void run() {
super.run();
while (progressBar.getProgress() <100){
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.setProgress(pb.getProgress()+10);
}
}
}.start();
}
My question is simple. Why it doesn't throw any CalledFromWrongThreadException?
If it meant to be this way, should we forget about Handler when we deal with progress updating?
https://cs.android.com/android/platform/superproject/+/android-10.0.0_r30:frameworks/base/core/java/android/widget/ProgressBar.java;l=1610
Bad luck--ProgressBar has special support for updating its progress from another thread. That's why it doesn't throw something.
But because it's so specifically this operation that has this extra support, no to the second question. You wouldn't, in general, stop using a handler. For cases where, for example, you need to do one other little UI thing while updating the progress.
I am trying to save data into a Firebase RealtimeDatabase.
The process of saving is fine and works just well, but I was curious about an idea I had: To force the .setValue operation into a synchronous structure. I know, that that way isn't the best one, but I wanted to try it regardless of that fact.
So I came up with this code:
Thread t1 = new Thread(){
public void run(){
try {
Tasks.await(databaseReference.child("someChild").setValue(someObject));
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finished");
}
In theory, that code snippet is intended to first set the value in the Database, then wait for the completion of that (through the Tasks.await()), and then print out **after that* the line "finished".
I wrapped the Tasks.await()-command in a second thread because when I don't, I get an exception which says something like "Tasks.await() must not be called in the main application thread".
But when I run the whole thing, it just gets stuck at t1.join();.
When I delete the t1.join();-statement, everything works just fine, but the second Thread (t1) isn't finished before the "finished"-output is there. I know why this is like that, but I am nontheless interested in a solution to that problem.
I wanted to know if there is a way in which the background thread that is trying to establish a connection on a passed uri string can be prevented from crashing the entire application due to IOException or MalformedURLException.
While I catch all the exceptions thrown and print the messages out to logcat, I wouldn't want the app to crash all together with the msg: Unfortunately, MyApp has stopped.
I would like the app to exit gracefully by posting a pertinent error message on the main/UI thread.
say for example:
public void onClick(View v){
new Thread(new MyDownloaderClass(url_str)).start();
}
private class MyDownloaderClass implements Runnable{
private String url_str;
public MyDownloaderClass(String arg){url_str=arg;}
public void run(){
URL url=null;
int respCode=0;
try{
url=new URL(str);
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
respCode=connection.getResponseCode();
}catch(MalformedURLException e){
Log.e(TAG,e.getClass()+": "+e.getMessage());
}catch(IOException e){
Log.e(TAG,e.getClass()+": "+e.getMessage());
}
}
}
In this case my app just crashes if the entered string is not a prasable url or a connection can't be made. But I want to be able post some useful message on UI thread and prevent the app from crashing.
thank you.
Then put it in the catch part
catch (Exception e) {
if(e.getMessage().toString().equalsIgnoreCase("write your exception from logcat"))
{
//show your error in a toast or a dialog
Toast.makeText(this," your pertinent error message ", Toast.LENGTH_LONG);
}
}
I would suggest you to do all network operations in AsyncTask.
In doinBackground() of AsyncTask method, perform all network operations with try/catch. Handle the exception as below.
//Define "Exception error = null;" in your AsyncTask class.
catch(Exception ex) {
Log.e(TAG,e.getClass()+": "+ex.getMessage());
error = ex;
}
In onPostExecute() method check for
if (error ! = null) {
//Toast msg . // You should not call a Toast msg in your doinBackground method.
}
you're wrongly using Thread.start() instead of Thread.run():
new Thread(new MyDownloaderClass(url_str)).start();
Your code still runs on the original thread, therefore on exception causing crash.
I must use Thread in an Android project. Sometimes, it works corectly, however sometimes does not; it does not start (does not call SendToServer() method)or it starts but return to another function suddenly (return updated; line)before the thread does not finish.
Note: affected value is bigger than 0, it gives condition and it goes to if statement.
Here is the my code sample;
public static Boolean MyUpdateFunction(MyObject myobject){
Boolean updated=false;
//Code for updating local database
int affected= SqliteDb.update(....);
if(affected>0)
{
//Send updated data to server
//For this I must use Thread(I can't use AsyncThread)
updated=true;
SendToServer();
}
return updated;
}
public static void SendToServer()
{
try{
;
Thread th=new Thread(new Runnable() {
public void run() {
try {
//Create data and send it to server
//.......
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
th.start();
th.join();
}
catch(SQLException e)
{
Toast.makeText(myContext,"ERROR: "+e.getMessage(), Toast.LENGTH_LONG).show();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Other people are correct in that an AsyncTask is the way forward, but the direct problem due to what you're experiencing is this (and as such, I would recommend reading up on how Threading works):
When you start the thread, it begins a new process. The UI thread (which is generally where the majority of your code is) continues. So your code will fire the thread with SendToServer(), and then by definition will immediately return updated, as the UI thread immediately goes to the next line.
What you need is a callback from your Thread, which is handled in the onPostExecute() method of an AsyncTask. There's a good tutorial on how to use them and what they do here
Edit:
I've just seen from a comment above that you can't use Asynctasks, fair enough, but you still need a callback/event fired from your Thread to return any results
Instead of using threads and your variables (updated and affected), you can use AsyncTasks: see: http://developer.android.com/reference/android/os/AsyncTask.html
With AsyncTask, you have some methods which are doing exactly what you want:
onPreExecute
doInBackground
onPostExecute
So, what you can do is to check your condition in onPreExecute, then do your SendToServer in the doInBackground and onPostExecute do what you need.
public void get(View view){
try {
asPt = new ProgressTask().execute(null,null,null);
Log.d("Watcher","Get finished");
}
catch (Exception e) {
e.printStackTrace();
Log.e("Watcher","Get Exception");
}
}
When I cancel(Boolean) the AsyncTask asPt the Line "Get finished" is never printed.
Why? It also doesn't catch an Exception in this method.
Remember cancel does nothing so you need to implement it yourself, see link: Android - Cancel AsyncTask Forcefully