Why AsyncTask make infinity loop - android

i always found the answer to my Questions in StackoverFlow but not this time, so i'm trying to ask it, and i hope that you can help me, and Thanks even if you coudn't.
I'm trying to use the mysql query
Select * From `Table`
and returning a resultset from asynctask using .get() the problem is that after executing the query and getting the returned value when the asynctask tries to get back in the program he loop infinity,
PS:when i use other query like "Select * From Table Where something = other thing" it works perfectly.
here 2 methodes in my class DataBaseManager which got 2 params: Conn type connexion and member type ResultSet
/* asynctask pour la connexion*/public void Selmem(String ...a){
final class Select_member extends AsyncTask<String, Integer, ResultSet> {
#Override
protected ResultSet doInBackground(String... params) {
try {
ResultSet member2;
String myDriver = "com.mysql.jdbc.Driver";
Class.forName(myDriver).newInstance();
conn = DriverManager.getConnection(params[0], "root", "");
if(params.length==6)
member2=select_member(params[1],params[2],params[3],params[4],params[5]);
else
member2=select_member(params[1],params[2],params[3]);
conn.close();
return(member2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("printf","NOT SELECTED");
return null;
}
// TODO Auto-generated method stub
}
}
try {
if(a.length==6)
member=new Select_member().execute(a[0],a[1],a[2],a[3],a[4],a[5]).get();
else
member=new Select_member().execute(a[0],a[1],a[2],a[3]).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public ResultSet select_member(String ...a){
String sql;
PreparedStatement prest;
try {
if(a.length==5)
{
sql="SELECT * FROM `"+a[0]+"` WHERE "+a[1]+" = '"+a[2]+"' and `"+a[3]+"` = '"+a[4]+"'";
prest= conn.prepareStatement(sql);
}
else if (a[2].equals(""))
{
sql="SELECT * FROM `"+a[0]+"`";
prest= conn.prepareStatement(sql);
}
else
{
sql="SELECT * FROM `"+a[0]+"` WHERE `"+a[1]+"` = '"+a[2]+"'";
prest= conn.prepareStatement(sql);
}
prest= conn.prepareStatement(sql);
ResultSet member1;
member1 = prest.executeQuery();
ResultSet member2=member1;
if(member1.next())
return member2;
else
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
this is where i Call my Class to try to Select from my database, ps: the program dosen't even get to my loop (so i don't think that my loop is the problem i used the debugger to see where is the problem)
public class Deniere_Op extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_deniere__op);
Intent activite=getIntent();
DataBaseManager base=new DataBaseManager();
String login=activite.getExtras().getString("login");
base.Selmem("jdbc:mysql://10.0.2.2:3306/db_app",login , "", "");
if(base.member==null)
{
Toast.makeText(getApplicationContext(), "Aucune Transaction",Toast.LENGTH_LONG).show();
}
else
{int i=0;
do{i++;
for(int j=1;j<=6;j++)
{String concat=new String();
concat=concat.valueOf(i)+concat.valueOf(j);
String message;
try {
message = base.member.getString(j);
String a="textview"+concat;
int resID=getResources().getIdentifier(a, "id",getPackageName());
TextView text=(TextView) findViewById(resID);
text.setText(message);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
base.member.next();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}while(base.member!=null);
}
}
I hope that this can make you understand my problem and helps you to help me :D :D.
the logcat hope it will help

Related

How to parse json in the class which extends Application in android

I have an AsyncTask class which parse json data and inserts into an object, when I call it in normal activity classes it shows that data have been parsed but when I execute this on a class which extends Application then it gives zero result. Here is my class
public class AppGlobalData extends Application {
public ArrayList<YoutubeItem> gotItem= new ArrayList<YoutubeItem>();
private YouTubeParser parser;
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
new ParserLoader().execute();
}
public class ParserLoader extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.i("Succeed?", "Yes");
parser = new YouTubeParser(
"http://powergroupbd.com/youtube/getyoutubejson.php");
try {
gotItem = parser.parseInitiator();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public ArrayList<YoutubeItem> getGotItem() {
return gotItem;
}
public void setGotItem(ArrayList<YoutubeItem> gotItem) {
this.gotItem = gotItem;
}
}
I cant figure out the problem, can anyone help?
please be noted that this class runs and logs my String but doesnt parse data.
I think what might happen is that when new ParserLoader().execute(); it doing the work asynchronously. When your Activity load and call the getGotItem() the Asynctask might not have finished

JSON Parsing in Android for pulling Boolean/Integer values

I am new to JSON and I was wondering how I would pull some info and put it into a JSON Object and then read some of the values. The json info looks like this,
{
"photos":{
"page":1,
"pages":1802,
"perpage":100,
"total":"180134",
"photo": [
{
"id":"8711964781",
"owner":"21156896#N07",
"secret":"3e24e45977",
"server":"8553",
"farm":9,
"title":"Old Harbor",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
{
"id":"8712680696",
"owner":"21156896#N07",
"secret":"fe82f8387b",
"server":"8122",
"farm":9,
"title":"Rockefeller Plaza",
"ispublic":1,
"isfriend":0,
"isfamily":0
},
....
It photo array goes on for quite a while. How would I get the values of "isPublic"? "Secret" is a String because of the "" and isPublic is an integer or boolean? I basically have to put them into a URL link and download the image.
public class ReadString extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
return json.getString(FlickrString[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tvTest.setText(result);
}
This works for all the strings. How would I get the farm, isfriend, isfamily, and ispublic converted to a string? I tried something else now to get the Int values, I made a whole new class for reading the ints. But it isnt getting the correct int value. I have it download the int and I convert it to a string and then I change a textview to the string of the int using String.valueOf(x); What am i doing wrong?
public class ReadInt extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... FlickrString) {
try {
json = getValue();
int x = json.getInt(FlickrString[0]);
String y = String.valueOf(x);
return y;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
tvTest.setText(result);
}
}
Thanks!
JSONObject jobj = result.getJSONObject("photo");
jobj.getBoolean("ispublic");
jobj.getInt("isfriend");
The variable result is of typeJsonObject that should contain the entire object have pasted above in your code
Java is not like C++.In C++ 0 is false and other integers are true
I think you should create a function like this
private void boolean convertIntToBool(int value) {
if(value==0) {
return false;
} else {
return true;
}
}
and use it in the JSON parsing like this for example
boolean isfamily = convertIntToBool(jsonPhotoObject.getInt("isfamily"));
I guess you already know about the JSON parsing so I won't give so much example, but if you have another question about my answer feel free to ask in the comment :)
we assume the jsonString is your json result. You can get the your values like this:
protected String doInBackground(String... FlickrString) {
try {
JSONObject result = new JSONBOject(jsonString);
JSONObject photots = (JSONObject)result.get("photos");
JSONArray photosArray = (JSONArray) result.get("photo");
for(int i = 0; i < photosArray.length(); i++) {
JSONObject item = potosArray.get(i);
//ispublic
int ispublic = item.getInt("ispublic");
//isfriend
int isfriend = item.getInt("isfriend");
//isfamily
int isfamily = item.getInt("isfamily");
}
json = getValue();
return json.getString(FlickrString[0]);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
I would recommend that you try either Jackson or Gson and convert the JSON into some POJOs. I find that it's easier and less error prone to work with java objects instead of JSONObject, JSONArray and such. Here's an example of how it would work using Jackson. First we create the Objects that map to the JSON data:
public class Photos {
#JsonProperty
private int page;
#JsonProperty
private int pages;
...
#JsonProperty("photo")
public List<Photo> photoList;
}
public class Photo {
#JsonProperty
private String id;
#JsonProperty
private String owner;
...
#JsonProperty("ispublic")
public boolean isPublic;
#JsonProperty("isfriend")
public boolean isFriend;
#JsonProperty("isfamily")
public boolean isFamily;
}
Once we've created our pojos we can convert the JSON data into objects using the ObjectMapper. AT least when it comes to Jackson it automatically tries to convert integers to boolean (0 = false, anything else = true) and Strings to booleans ("true" and "false").
ObjectMapper mapper = new ObjectMapper();
Photos photos = mapper.readValue(json, Photos.class);
for(Photo photo : photos.photoList) {
if(photo.isPublic) {
// do something
}
}
PS I've made some of the properties of the pojos public to make the example shorter. You may wish to add getters and keep the properties private.

Android ListView loading before data has been downloaded - have to restart view

I am using a New Runnable httprequest data loading in one of my classes. I use that class to populate a ListView in one of my Activities, but the thing is that the views are loading before the data has been loaded.. I tried moving my initialize method, which initializes all views, but nothing happened. Every time I load the app, I have to reload the main view because there are no entries in the ListView. LoadReportList() is the method that makes an instance of the class holding the http request method.
public class HomeActivity extends Activity {
private ArrayList<Report> reportList = null;
ListView listview;
private final boolean DEBUG = true;
private MyCustomArrayAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
}
#Override
protected void onResume()
{
super.onResume();
loadReportList();
initialize();
}
/**
* This method initializes all the components needed for the activity
*/
private void initialize()
{
/* Get a reference of the listview in our xml view */
listview = (ListView) findViewById(R.id.reportsList);
adapter = new MyCustomArrayAdapter(this, R.layout.single_listview_row);
try{
// Populate the list, through the adapter
for(final List_Item entry : getListEntries()) {
adapter.add(entry);
if(DEBUG)Log.i("HomeActivity","in adding List_Item entries to the adapter");
}
}catch(Exception e){
Log.i("In initialize() HomeActivity","Could not load the list with entries");
loadReportList();
}
listview.setAdapter(adapter);
listview.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
/* Class to assist us in loading the activity */
Class editClass = null;
try {
editClass = Class.forName(".DetailsActivity");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/* create bundle to pass the ID of the deck that was clicked */
Bundle reportPassed = new Bundle();
//reportPassed.putInt("Report", reportList.get(4).getId());
reportPassed.putSerializable("report", reportList.get(position));
/* Start the new intent and also pass a bundle that will contain the name of the card that was clicked */
Intent ourIntent = new Intent(HomeActivity.this, editClass);
ourIntent.putExtras(reportPassed);//passing the bundle to the activity
//start the activity
startActivity(ourIntent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
/* Create the list of objects of type List_Item, in our case it will be Decks */
private List<List_Item> getListEntries(){
/* Create an ArrayList of List_Items */
final ArrayList<List_Item> entries = new ArrayList<List_Item>();
if(reportList == null || reportList.isEmpty())
loadReportList();
/* Create the rows for the ListView by adding them into the ArrayList "entries".
* reportList is a global ArrayList<Report> that we populate by a method call to the class JsonParser.
* Look above.
* */
for(int i = 0; i < reportList.size(); i++) {
if(DEBUG)Log.i("getListEntries HomeActivity","Passing through reportlistEntries");
entries.add(
new List_Item(((Report)reportList.get(i)).getType(), Integer.toString(((Report)reportList.get(i)).getId()), ((Report)reportList.get(i)).getId())
);
}
return entries;
}
//This method loads the reportList arraylist with all Report objects
void loadReportList(){
try {
reportList = new JsonParser().getArrayList();
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Here is my HTTP request:
//The constructor simply calls the getHttpResponse()
public JsonParser() throws UnsupportedEncodingException, IllegalStateException, IOException, JSONException
{
getHttpResponse();
}
/*
* This method returns an HttpResponse
*/
public void getHttpResponse(){
Log.i("getHttpResponse", "Right after declaring HttpResponse response");
new Thread(new Runnable() {
public void run() {
runRequest();
}
}).start();
}
void runRequest()
{
HttpResponse response = null;
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
try {
request.setURI(new URI("http://....../report_data.json"));
response = client.execute(request);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(response!= null)
Log.i(response.toString(), "testing response.toString()");
//call to populate the list
try {
populateList(response);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Instead of using a java thread you can take advantage of the AsyncTask class of the Android SDK. You can show a progress dialog onPreExecute method, do all the heavy work(in your case the http stuff) in the doInBackground method and populate your list and dismiss the progress dialog in the onPostExecute method. You can create an inner class e.g Task which extends the AsyncTask method and call it from onCreate or onResume ,whatever suits you, like this.
new Task().execute();
AsyncTask has given the name"Painless threading" because it is there to make our life easier. It is consider good practice to reuse already implemented code which is intended for such tasks.
You can find many threads regarding AsyncTasks use in StackOverflow e.g progressDialog in AsyncTask
So what you need to do is call initialize() after your runRequest code completes.
I agree with the above poster that an AsyncTask will make this easy. Get rid of the threading code in your JsonParser class. AsyncTask will take care of that for you.
Here's a snippet.
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
myparser = new JSONParser();
myparser.runRequest()
}
#Override
protected void onPostExecute(Void aVoid) {
initialize();
}
}.execute();

onPostExecute not being called by ASyncTask execute()

I can't explain why onPostExecute is not being called in my code. I have successfully used almost this exact code with a different app before. It prints 'onPreExecute' and the successful result of the JSON fetch from doInBackground just before return result; but then onPostExecute doesn't print anything - with the super call or not - and moreover doesn't return my string to the UI thread. Any ideas?
public class PrivateLoadFromServer extends AsyncTask<String, Integer, String> {
InputStream is = null;
String result = null;
String error_text="";
JSONObject j = null;
String url;
SQLiteOpenHelper helper;
CustomActivity activity;
private Context context;
private ProgressDialog dialog;
private int count;
String employee;
String text;
public PrivateLoadFromServer(CustomActivity activity,String employee,String url){
this.url=url;
this.employee=employee;
this.activity=activity;
}
#Override
protected void onPreExecute() {
system.out.println("onPreExecute");
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
System.out.println("onPostExecute");
activity.setJSONResult(result);
/*
if(result!=null){
System.out.println("Task reported successful");
taskHandler.taskSuccessful(this.result);
activity.setJSONResult(this.result);
} else {
taskHandler.taskFailed();
}
*/
//return;
}
#Override
protected String doInBackground(String... params) {
System.out.println("Running aSyncTask");
// Successful code to get JSON result string from server omitted.
System.out.println("Raw at doInBackground: " + result);
return result;
EDIT: Should've posted this originally, I call it as an inner class in CustomActivity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
helper=new DBHelper(this);
loadBasicData();
}
private void loadBasicData() {
// If you can encode all of these into one JSON Object, cool.
String url="*****" //Omitted URL.
String employee=null;
PrivateLoadFromServer syncTask = new PrivateLoadFromServer(this,employee,url);
syncTask.execute();
try {
syncTask.get(15000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("JSONResult at Activity:"+jsonResult); // jsonResult is null
}
}
public void setJSONResult(String result){
System.out.println("setJSONResult"+result);
this.jsonResult=result; // jsonResult is a field in the Activity.
}
Because you are calling get, the JSON result is also returned from this method (see the source code of AsyncTask.java. So you can call your method directly on the output.
try {
setJSONResult(syncTask.get(15000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
Check if your are explicitly cancelling AsyncTask somewhere in the code before it could postExecute.
onPostExecute() is called on the main UI thread. If its not getting called, it means your UI thread is blocked doing something else.

Waiting for result in IntentService

Is there a way to wait for the result when using IntentService?
Scenario.
Service App is running --> receives login credentials from another app --> Service app then checks database (for some reason I always get Connection time out. And I know this is bad but for POC and a quick hack this will do for now) --> Wait for validation query then results.
Is this possible?
I tried using AsynTask inside the Service but still to no avail, I always get Connection timeout error.
DEMOSERVICE
#Override
public IBinder onBind(Intent intent) {
return new IDemoService.Stub() {
#Override
/**
* Login validation implementation
*/
public boolean login(String id, String password)
throws RemoteException {
UserLoginTask userLoginTask = new UserLoginTask(id, password);
try {
return userLoginTask.execute((Void) null).get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
};
}
USERLOGINTASK
private class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private String uId;
private String uPassword;
public UserLoginTask(String id, String password) {
uId = id;
uPassword = password;
}
#Override
protected Boolean doInBackground(Void... arg0) {
Connection conn;
try {
int count = 0;
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://xxx.xxx.x.xxx/test_db?user=postgres&password=password";
conn = DriverManager.getConnection(url);
if (conn != null) {
Statement st = conn.createStatement();
String sql = "Select count(*) as cnt from tbl_persons where id = '"
+ uId.toUpperCase(Locale.getDefault()).trim()
+ "' AND pwd='" + uPassword.trim() + "';";
Log.d("DemoService", "Login sql - " + sql);
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
count = rs.getInt("cnt");
}
rs.close();
st.close();
conn.close();
if (count == 0)
return false;
return true;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}

Categories

Resources