from the beginning i used this method :
public Drawable createPortrait(String url){
try {
InputStream is = (InputStream)new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "Image");
return d;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
but honeycomb doesn't allow me to do it anymore, what i see in my log is : android.os.networkonmainthreadexception .
the thing is that my url is already taken from json data :
private class GrabURL extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog Dialog = new ProgressDialog(Main.this);
protected void onPreExecute() {
Dialog.setMessage("Downloading source..");
Dialog.show();
}
protected Void doInBackground(String... urls) {
try {
HttpGet httpget = new HttpGet(urls[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
Content = Client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
Error = e.getMessage();
cancel(true);
} catch (IOException e) {
Error = e.getMessage();
cancel(true);
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
if (Error != null) {
Toast.makeText(Main.this, Error, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(Main.this, "Source: " + Content, Toast.LENGTH_LONG).show();
}
Object o = new Gson().fromJson(Content, Info.class);
Info i = (Info)o;
String d = i.getData().get(0).getLg_portrait();
portrait.setBackgroundDrawable(createPortrait(d));
}
}
and portrait is an ImageView . i don't know what to do .
You need to download the image in Async task as well. Honeycomb simply does not let you run lengthy HTTP operation blocking the UI thread (reading from stream makes HTTP call and waits for the image to be downloaded). You should return some placeholder immediately, trigger AsyncTask and replace the image after it is already downloaded.
Hint "post execute" is run in UI thread....
Related
I have push Notification and I want to update realm objects when the phone gets a notification but when I try launch this:
RealmModelActiveUser actUser= realm.where(RealmModelActiveUser.class).equalTo("id",1).findFirst();
int myid= actUser.getUser().getUser_id();
new ServerBackgroundDownloadConversations(getApplicationContext()) {
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (!result.equals("Error")) {
Log.i("Conversation", "UPDATED");
}
}
}.execute(myid);
The program jumps into the constructor ServerBackgroundDownloadConversations(getApplicationContext()) but doesn't call doInBackground and I don't know why.
My AsyncTask:
public class ServerBackgroundCreateConversation extends AsyncTask<RealmModelConversations,Void,String> {
Context context;
Handler handler;
String out= "";
#SuppressLint("HandlerLeak")
public ServerBackgroundCreateConversation(Context context) {
this.context = context;
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
Bundle bundle= msg.getData();
if (bundle!=null){
out = (String) bundle.get("response");
} else {
out= "Error";
}
}
};
}
#Override
protected String doInBackground(RealmModelConversations... params) {
RealmModelConversations newConv = params[0];
UploadImageApacheHttp uploadTask = new UploadImageApacheHttp();
uploadTask.doFileUpload(newConv.getWork(newConv.getIntWork()), newConv, handler);
while (out.equals("")){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return out;
}
#Override
protected void onPreExecute() {
}
#Override
protected void onPostExecute(String result) {
if (!result.equals("]") || !result.equals("")){
/// prihlási nového user aj do active (login/register)
CreateNewConversation(result);
} else {
result="Error";
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
private void CreateNewConversation(String result){
Realm realm= Realm.getDefaultInstance();
try {
Gson gson = new Gson();
Type typeConv = new TypeToken<JsonSablonaConversations>() {
}.getType();
JSONObject pom;
JSONArray parentArray = new JSONArray(result);
JSONObject finalObject = parentArray.getJSONObject(0);
JsonSablonaConversations conversation = gson.fromJson(finalObject.toString(), typeConv);
final RealmModelConversations NewUserConv = new RealmModelConversations();
NewUserConv.setId_dialog(conversation.getId_dialog());
NewUserConv.setDate(conversation.getDate());
NewUserConv.setKey(conversation.getKey());
NewUserConv.setId_user(conversation.getId_user());
NewUserConv.setId_user2(conversation.getId_user2());
NewUserConv.setMeno(conversation.getMeno());
NewUserConv.setMeno2(conversation.getMeno2());
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
try {
realm.copyToRealmOrUpdate(NewUserConv);
} catch (Exception e) {
int pom=4;
}
RealmResults<RealmModelConversations> ru= realm.where(RealmModelConversations.class).findAll();
}
});
}
catch (Exception e) {
int ppp=4;
ppp++;
}finally {
realm.close();
}
}
}
I try calling this ↑ from an external thread which is called from a Service, but my AsyncTask has handler and handler needs to be in runOnUIthread and in Thread. I can't get Activity because the thread is called from a Service which doesn't have access to Activity.
I solved my problem with this code
public String postData(int myUserId) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.gallopshop.eu/OFY/getConversations.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", Integer.toString(myUserId)));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String responseStr = EntityUtils.toString(response.getEntity());
return responseStr;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
return null;
}
I will try to put this method & after this method into simply thread, But maybe it's not needed because it's in a service.
Question - Do I put this into Thread or do you think it'll affect the performance of the app?
These are my MainActivity:
database_connector wp_terms = new database_connector("SELECT * FROM `dse120071750`.`wp_terms` ",progressDialog,this);
wp_terms.execute();
wp_terms.onPreExecute();
try {
for (int i=0; i<wp_terms.getJsonArray().length(); i++){
JSONObject obj = wp_terms.getJsonArray().getJSONObject(i);
this.wp_terms.put(obj.getString("term_id"), obj.getString("name"));
}
} catch (JSONException e) {
e.printStackTrace();
}
DatabaseConnector:
package hk.hoome.www.mobilehoome;
public class database_connector extends AsyncTask<Void,Void, Void> {
//String mode;
HttpResponse response;
String sql;
JSONArray jsonArray;
searchPage searchPage;
public database_connector(String sql, searchPage searchPage){
//this.mode = mode;
this.sql = sql;
this.searchPage = searchPage;
jsonArray = new JSONArray();
}
#Override
protected Void doInBackground(Void... params) {
connect();
publishProgress();
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
}
public void connect() {
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
nameValuePair.add(new BasicNameValuePair("sql", sql));
//nameValuePair.add(new BasicNameValuePair("mode", mode));
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.hoome.hk/hoomeMobileApps/connectDB.php");
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
response = httpClient.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
String entityResponse = EntityUtils.toString(httpEntity);
Log.e("Entity Response ", entityResponse.substring(2));
jsonArray = new JSONArray(entityResponse.substring(2));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
public JSONArray getJsonArray(){
return jsonArray;
}
}
When I ran this code, for (int i=0; i<wp_terms.getJsonArray().length(); i++){ this results in a nullPointerException.
I believe that this is because doInbackground hasn't finished its process but mainActivity keeps running. How can I set that doInbackground has to be done before continue running the mainActivity?
SOLUTION?
try {
while (wp_posts.getJsonArray().equals(null))
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
is this a good solution?
Use a callback in your database connector class and pass the completion callback. For the simplicity I'm using Runnable interface. In general, try to have your own interface and also to pass the params between the background thread and the main thread over your custom interface.
package hk.hoome.www.mobilehoome;
public class database_connector extends AsyncTask<Void,Void, Void> {
//String mode;
HttpResponse response;
String sql;
JSONArray jsonArray;
searchPage searchPage;
private Runnable activityCallback;
public void setCallback(Runnable callback) {
this.activityCallback = callback;
}
public database_connector(String sql, searchPage searchPage){
//this.mode = mode;
this.sql = sql;
this.searchPage = searchPage;
jsonArray = new JSONArray();
}
#Override
protected Void doInBackground(Void... params) {
connect();
publishProgress();
return null;
}
protected void onPostExecute(Void result) {
if(activityCallback != null) {
activityCallback.run();
}
}
#Override
protected void onProgressUpdate(Void... values) {
}
public void connect() {
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1);
nameValuePair.add(new BasicNameValuePair("sql", sql));
//nameValuePair.add(new BasicNameValuePair("mode", mode));
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.hoome.hk/hoomeMobileApps/connectDB.php");
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
response = httpClient.execute(httpPost);
HttpEntity httpEntity = response.getEntity();
String entityResponse = EntityUtils.toString(httpEntity);
Log.e("Entity Response ", entityResponse.substring(2));
jsonArray = new JSONArray(entityResponse.substring(2));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
public JSONArray getJsonArray(){
return jsonArray;
}
}
In your MainActivity
database_connector wp_terms = new database_connector("SELECT * FROM `dse120071750`.`wp_terms` ",progressDialog,this);
wp_terms.setCallback(new Runnable() {
public void run() {
try {
for (int i=0; i<wp_terms.getJsonArray().length(); i++){
JSONObject obj = wp_terms.getJsonArray().getJSONObject(i);
this.wp_terms.put(obj.getString("term_id"), obj.getString("name"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
wp_terms.execute();
I also faced the same problem in one of my project, this is what might help you
public class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(String...params) {
String result;
//background tasks here.
return result;
}
protected void onPostExecute(String result) {
//task after doInBackground here.
}
}
doInBackground():
Override this method to perform a computation on a background thread.
onPostExecute():
Runs on the UI thread after doInBackground(Params...). The specified result is the value returned by doInBackground(Params...).
This method won't be invoked if the task was cancelled.
Parameters
result The result of the operation computed by doInBackground(Params...)
perform the background task in doInBackground method and the task after the background task(displaying toast or dialog) in onPostExecute(String result) method.
The result returned from doInBackground(String...params)method will be received as parameter in onPostExecute(String result) method in result parameter.
To use this code segment, from your main activity call new DownloadFilesTask().excute(param1,param2,...,paramn).
This parameters will be received in doInBackground(String...params) in params.
Write in comment if you face any problem.
Happy coding!!!
I coded a class which starts a http connection for getting the text of e.g. website.
I used AsyncTask but I got NetworkOnMainException. May u help me?
The class
public class getXMLData extends AsyncTask<String, Void, String> {
TextView _textview;
public getXMLData(TextView textview) {
_textview = textview;
}
protected String doInBackground(String... url)
{
String _text = "";
try {
try {
URL _url = new URL(url[0]);
HttpURLConnection con = (HttpURLConnection) _url.openConnection();
_text = readStream(con.getInputStream());
}
catch (Exception e) {
e.printStackTrace();
}
}
catch (Exception e) {
e.printStackTrace();
}
return _text;
}
protected void onPostExecute(String result)
{
_textview.setText(result.toCharArray(), 0, result.length());
}
private String readStream(java.io.InputStream in) {
java.io.BufferedReader reader = null;
String result = "";
reader = new BufferedReader(new InputStreamReader(in));
try {
while ((reader.readLine() != null)) {
result = result + reader.readLine();
}
}
catch (java.io.IOException i)
{
}
finally
{
try {
reader.close();
}
catch (java.io.IOException e) {
e.printStackTrace();
}
}
return result;
}
Here how I start the AsyncTask:
bu_aktualize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
_getXMLData.doInBackground("http://www.google.de");
}
});
Thanks for your help.
You do not call doInBackground() yourself. Instead, you call execute() or executeOnExecutor() to start the AsyncTask.
You may wish to review the documentation for AsyncTask, which shows an example of setting up an AsyncTask, including a call to execute().
In my main page, I'm calling an AsyncTask that is its own class.
new DownloadFileAsync(context, icon, resultp.get(PublicProfilePage.REVIEWCREATORFBOOKID),"300").execute();
Below is my AsyncTask. I'm reading a JSON trying to get the image's URL. Once I capture that URL I use ImageLoader to cache it, but it does not work.
public class DownloadFileAsync extends AsyncTask<Void, Void, String> {
//private Context context;
CircularImageView bmImage;
ImageLoader imageLoader;
String fbook_id;
String jsonobject;
String image_size;
String size_url;
public DownloadFileAsync(Context context, CircularImageView bmImage, String fbook_id, String size)
{
//this.context = context;
this.bmImage = bmImage;
this.fbook_id = fbook_id;
this.image_size = size;
//Image Loader Initialization
imageLoader = new ImageLoader(context);
if(image_size.equalsIgnoreCase("150")) {
size_url = "https://graph.facebook.com/v2.1/" + fbook_id + "/picture?redirect=0&height=150&width=150";
}else if(image_size.equalsIgnoreCase("300")) {
size_url = "https://graph.facebook.com/v2.1/" + fbook_id + "/picture?redirect=0&height=300&width=300";
}
}
protected String doInBackground(Void... urls) {
String result = null;
String queryResponse = null;
String resultTwo = null;
// Create a new HttpClient and Post Header
HttpClient httpclientBankCheck = new DefaultHttpClient();
HttpGet httppostBankCheck = new HttpGet(size_url);
try {
// Execute HTTP Post Request
HttpResponse responseBankCheck = httpclientBankCheck.execute(httppostBankCheck);
HttpEntity responseText = responseBankCheck.getEntity();
queryResponse = EntityUtils.toString(responseText);
// Retrive JSON Objects from the given website URL in
// JSONfunctions.class
jsonobject = queryResponse;
// Locate the array name
JSONObject arr = new JSONObject(jsonobject);
result = arr.getString("data");
JSONObject arrTwo = new JSONObject(result);
resultTwo = arrTwo.getString("url");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return resultTwo;
}
protected void onPostExecute(String resultTwo) {
//bmImage.setImageBitmap(result);
imageLoader.DisplayImage(resultTwo, bmImage);
}
}
If I hard code the URL into ImageLoader inside my main page, it does work. Is the problem that I'm using an AsyncTask with ImageLoader? It shouldn't be right?
Really appreciate the help!
-M
Hi Please Can someone help me look at this code? Don't know what am doing wrong,But the try block doesn't run. instead it goes to the catch block.
public void onClick(View arg0) {
//Toast.makeText(getBaseContext(), "connecting",Toast.LENGTH_SHORT).show();
// TODO Auto-generated method stub
httpclient = new DefaultHttpClient();
htpost = new HttpPost("http://10.0.2.2/fanaticmobile/log_in.php");
uname= username.getText().toString();
pass= password.getText().toString();
try {
namearray = new ArrayList<NameValuePair>();
namearray.add(new BasicNameValuePair("username", uname));
namearray.add(new BasicNameValuePair("password", pass));
htpost.setEntity(new UrlEncodedFormEntity(namearray));
response= httpclient.execute(htpost);
if(response.getStatusLine().getStatusCode()==200){
entity= response.getEntity();
if(entity != null){
InputStream stream = entity.getContent();
JSONObject jresponse = new JSONObject(ConvertInput(stream));
String logged= jresponse.getString("logged");
login_err.setText(""+logged);
if(logged.equals("true")){
Toast.makeText(getBaseContext(), "Successfull",Toast.LENGTH_SHORT).show();
//String retname= jresponse.getString("name");
//String retmail= jresponse.getString("email");
}else if(logged.equals("false")){
String message=jresponse.getString("message");
Toast.makeText(getBaseContext(), message,Toast.LENGTH_SHORT).show();
}
}
}else{
}
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(getBaseContext(), "Poor Connection",Toast.LENGTH_SHORT).show();
}
}//
This is the function to read the json object
private static String ConvertInput(InputStream is){
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line ="";
try {
while((line = reader.readLine())!= null){
sb.append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
is.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
return sb.toString();
}// end of convert function
Please am new to this and i followed a tutorial to this point,but mine is not working. Have set permission(internet) in the manifest file
I have a suggestion Try to Use AsyncHttpclient for getting responses from server no need of this long codes.
http://loopj.com/android-async-http/
AsyncHttpClient asyncHttpClient=new AsyncHttpClient();
RequestParams params=new RequestParams();
params.put("username", uname);
params.put("password", pass);
asyncHttpClient.post("http://10.0.2.2/fanaticmobile/log_in.php", params,new AsyncHttpResponseHandler(){
#Override
public void onFailure(Throwable arg0, String arg1) {
// TODO Auto-generated method stub
super.onFailure(arg0, arg1);
}
#Override
public void onSuccess(String arg0) {
// TODO Auto-generated method stub
super.onSuccess(arg0);
}
});
Just include the jar file in your project it will be simple to use.
Like already been stated in the comments, you're running a network operation in your main thread (the UI thread). This is not only discouraged (lengthy operations should never use the Main Thread), but also forbidden in the case of networking.
response= httpclient.execute(htpost)
^ this fails.
Read how to move that code to an AsyncTask and do it the right way in the official google reference. Googling AsyncTask will help too.
A Pseudo Code version would be:
public class YourTask extends AsyncTask<Void, Void, Void>{
YourListener mListener;
public YourTask(final YourListener listener) {
mListener = listener;
}
#Override
protected Void doInBackground(final Void... params) {
// do your lengthy operation here
return null;
}
#Override
protected void onPostExecute(Void result) {
mListener.onVeryLongTaskDone();
}
public interface YourListener {
public void onVeryLongTaskDone();
}
}
Then make your activity implement that "YourListener" interface and the method onVeryLongTaskDone() will be called.
How do you start the task?
in your onClick method:
(new YourTask(YourActivityName.this)).execute();