I`m trying to get a String from URL and create an objects by Gson. I am getting to string from this url: http://gotachles.co.il/data.php and then I have to convert it to html before sending it to Gson. The problem is that my string is probably too long (1.5 million letters) and the app freeze when calling fromHTML. (tried and it works fine with smaller strings).
TachlesStringGetter:
class TachlesStringGetter extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
String myJSONString = null;
try {
myJSONString = new Scanner(new URL(
"http://gotachles.co.il/data.php").openStream(), "UTF-8")
.useDelimiter("\\A").next();
Log.i("TACHLESSTRINGGETTER", "got sucessfuly");
Log.i("TACHLESSTRINGGETTER", "" + myJSONString.length());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("TACHLESSTRINGGETTER", "RETURN");
return myJSONString;
}
}
The HTML asynctask:
public class FromHTML extends AsyncTask<String, String, String> {
private Spanned spanned;
private String result;
#Override
protected String doInBackground(String... html) {
Log.i("FROMHTML", "STARTING");
spanned = Html.fromHtml(html[0]);
result = spanned.toString();
Log.i("FROMHTML", "Returning");
return result;
}
}
Calling it like that:
public void Jsonnn() {
// sending to anynctask
try {
myJSONString2 = new TachlesStringGetter().execute(myJSONString2)
.get();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
// // from html
if (myJSONString2 != null) {
Log.i("WEBVIEWCLASS", "DOING HTML STUFF");
try {
afterHTML = new FromHTML().execute(myJSONString2).get();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ExecutionException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} finally {
Log.i("FINALLY", "STARTING SEOND FINALLY");
try {
Gson gson = new Gson();
JsonObj obj = gson.fromJson(afterHTML, JsonObj.class);
Toast.makeText(getApplicationContext(), obj + "", 2000)
.show();
} catch (JsonSyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(getApplicationContext(), "oops jsno!",
1000).show();
}
}
}// first finnaly
}// second finnaly
}
Sorry for the shitty code :D
StringBuilder consume less memory than using String addition (str = str1 + str2). An example use of a StringBuilder:
StringBuilder builder = new StringBuilder();
builder.append("This is my string");
To get your long string from your builder (when you are trying to convert it to Gson object) you can simply call builder.toString();
So you should edit your Asynctask class "TachlesStringGetter" which should use a StringBuilder, you should also change other aspects of your code whenever you use something to append to String. The + operator uses public String concat(String str) internally. This method copies the characters of the two strings, so it has memory requirements and runtime complexity proportional to the length of the two strings. StringBuilder works more efficent. Hope this helps!
Related
I am getting html source from Aozora Bunko. Html file is Shift-JIS encoded. I am trying to get book title and author. Then I want to record title and author into SQLite(UTF-8) database.
String[] splittedResult = result.split("\"title\">");
splittedResult = splittedResult[1].split("</h1>");
String title = splittedResult[0];
byte[] b = null;
try {
b = title.getBytes("Shift_JIS");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String value=null;
try {
value = new String(b, "UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
...
myDatabase.addBookInformation(value, author);
Result is like this: latin letters are showing normally. But japanese letters are shown by blocks question mark inside (please do not pay attention to null values)
How to solve this problem?
As #Codo pointed out, solution for this problem was before.
I changed this
s = EntityUtils.toString(response.getEntity(), "UTF-8");
to this
s = EntityUtils.toString(response.getEntity(), "Shift_JIS");
And now there is no need for encoding.
String[] splittedResult = result.split("\"title\">");
splittedResult = splittedResult[1].split("</h1>");
String title = splittedResult[0];
/** I HAVE TAKEN THIS PART OF MY CODE
byte[] b = null;
try {
b = title.getBytes("Shift_JIS");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String value=null;
try {
value = new String(b, "UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
**/
I am new in android.I need to take values from web service.Here i used json parsing.The out put Json format is { "flag": 0 }. Here i need to take the value of flag and using that value i want to start another method. How do i take the value of flag. please help me. I used in this way.
public String objectvalue(String result){
try {
JSONObject obj=new JSONObject(result);
String flag=obj.getString("flag");
mString=flag;
System.out.println(mString);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return mString;
}
But i didnot get the value of flag.Here argument result is output from the server.ie,result={ "flag": 0 }
First of all, where is the declaration of mString variable? I assume it is declared as instance variable in your java class having this method, if not please check.
You have a well formed JSON in the form of
{ "flag": 0 }
so converting it to a JSONObject should work perfectly.
For extracting value of flag key
There is key named flag in this JSONObject which has an Integer value and you are trying to extract it using getString() method.
You should be using either of the following methods calls
optInt(String key)
Get an optional int value associated with a key, or zero if there is no such key or if th value is not a number. If the value is a string, an attempt will be made to evaluate it as a number.
int flag = optInt("flag");
OR
optInt(String key, int defaultValue)
Get an optional int value associated with a key, or the default if there is no such key or if the value is not a number. If the value is a string, an attempt will be made to evaluate it as a number.
int flag = optInt("flag", 0);
Your code with changes
public int objectValue(String result){
int flag = 0;
try {
JSONObject obj=new JSONObject(result);
flag = obj.optInt("flag");
} catch (JSONException e) {
e.printStackTrace();
}
return flag;
}
Edit: Answer to question in comment.
public String objectValue(String result){
int flag = 0;
try {
JSONObject obj=new JSONObject(result);
flag = obj.optInt("flag");
} catch (JSONException e) {
e.printStackTrace();
}
return String.valueOf(flag);
}
Hope this helps.
You may try using AsyncTask for your concern. It's best and preffered way to fetch JSON data
Define AsyncTask like this ..
new BussinessOwnerHttpAsyncTask().execute();
and your AsyncTask class ..
class BussinessOwnerHttpAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// Progress dialog code goes over here ..
pDialog = new ProgressDialog(getParent());
pDialog.setMessage("Please wait ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
// Maintaining Shared preferences class for further...
HttpClient httpclient = new DefaultHttpClient();
String myUrl = Your_url_goes_over_here;
String encodedURL = "";
try {
encodedURL = URLEncoder.encode(myUrl, "UTF-8");
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
URL url = new URL(encodedURL);
Log.d("asca", ""+url);
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Log.i("url", city_name + "~" + country_name);
Log.d("location", request_url+encodedURL);
HttpGet httpget = new HttpGet(request_url+encodedURL);
try {
httpresponse = httpclient.execute(httpget);
System.out.println("httpresponse" + httpresponse);
Log.i("response", "Response" + httpresponse);
InputStream is = httpresponse.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String recievingDataFromServer = null;
while ((recievingDataFromServer = br.readLine()) != null) {
Log.i("CHECK WHILE", "CHECK WHILE");
sb.append(recievingDataFromServer);
}
myJsonString = sb.toString();
Log.d("manish", myJsonString);
serverSearchData = sb.toString();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pDialog.dismiss();
if (myJsonString.length() > 0) {
try {
myJsonObject = new JSONObject(myJsonString);
String your_flag = myJsonObject.getString("flag");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Now you are good to go with your queries..
{ // JSONObject
"flag": 0
}
Use
JSONObject obj=new JSONObject(result);
int flag=obj.getInt("flag");
http://developer.android.com/reference/org/json/JSONObject.html
public int getInt (String name)
Added in API level 1
Returns the value mapped by name if it exists and is an int or can be coerced to an int.
Throws
JSONException if the mapping doesn't exist or cannot be coerced to an int.
If this does not work you need to post more info.
the "flag" values format at interger, not string, this is simple code to do that :
int flagValues = jsonObject.getInt("flag");
Log.w("values ",String.valuesOf(flagValues));
I am looking to pull data from my websites JSON url and display only one object in the textview. I was able to parse the entire JSON array, but not the specific object.
Here's the JSON on the site:
{"id":3,"day":" an A","created_at":"2013-11-06T12:30:59.023Z","updated_at":"2013-11-06T12:30:59.023Z"}
As you can see, it's pretty simple, but basically all I want to pull is the
"day":" an A"
and display it in my textview as "an A". Until now, I've only been able to pull the entire array.
A reference to this or any solution would be greatly appreciated!
Thanks in advance!
MainActivity Class:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parseDay);
TextView textView1 = null;
try {
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
JSONObject json=new JSONObject("day");
try {
String day =json.getString("day");
textView1.setText(day);
} catch (JSONException e) {
e.printStackTrace();
}
}
//catch (JSONException e) {
// e.printStackTrace();
//}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and My GetMethod:
public class GetMethod {
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.xelatechnologies.com/hfdays/show.json");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
}
finally {
if (in !=null){
try{
in.close();
return data;
}catch (Exception e){
e.printStackTrace();
}
}
}
}
I'm extremely new to JSON parsing so I'm sure it is not right at all. But it's worth a try!
The JSON you posted is a JSONObject. In java you can put that object into an JSONObject like this (You can use any serialize/deserializer you would like, many exist, for this example try org.json):
String json = "{\"id\":3,\"day\":\" an A\",\"created_at\":\"2013-11-06T12:30:59.023Z\",\"updated_at\":\"2013-11-06T12:30:59.023Z\"}";
JSONObject jsonObject = new JSONObject(json);
Now you have created a json object. Next you want to set the text on the text view. The key to get your value in this case is "day". So now all you have to do is use the provided getString(String value) method on the json object.
final String DAY = "day";
String dayValue= "";
try {
value = jsonObject.getString(DAY);
} catch (JSONException e) {
e.printStackTrace();
}
TextView textView = findViewById(R.id.text_view);
textView.setText(dayValue);
{"id":3,"day":" an A","created_at":"2013-11-06T12:30:59.023Z","updated_at":"2013-11-06T12:30:59.023Z"}
As its starts from '{' so it is an Object not Array
JSONObject json=new JSONObject("YOUR_JSON_STRING");
try {
String days=json.getString("day");
textview.setText(days);
} catch (JSONException e) {
e.printStackTrace();
}
Edited:
TextView textView1;
String response;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parseDay);
textView1 = (TextView)findViewById(R.id.your_textview_id);//First Initialise TextView
GetMethod method=new GetMethod();
response=method. getInternetData();// Then get the Json response
try{
JSONObject json=new JSONObject(response);
try {
String day =json.getString("day");
textView1.setText(day);
} catch (JSONException e) {
e.printStackTrace();
}
}
catch (JSONException e) {
e.printStackTrace();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
And dont forget to add Internet Permission in Manifest file
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Try like this.
I am using FTP to upload a file. This works great. This file contains information what the app should do.
So I am doing the following:
1) Download the file with Apache FTP Client (seems to work fine)
2) Try to read out the file with a BufferedReader and FileReader.
The problem:
I get a NullPointerException while reading the file. I guess that this is a timing problem.
The code has this structure:
...
getFile().execute();
BufferedReader br = new BufferedReader(...);
How can I solve this problem?
I have to use a seperate Thread (AsyncTask) to download the file because otherwise it will throw a NetworkOnMainThread Exception.
But how can I wait until the file is completely downloaded without freezing the UI?
I cannot use the BufferedReader inside AsyncTask because I use GUI elements and I have to run the interactions on the GUI Thread, but I have no access to it from AsyncTask. RunOnUiThread does not work as well because I am inside a BroadcastReceiver.
Some code:
private class GetTask extends AsyncTask{
public GetTask(){
}
#Override
protected Object doInBackground(Object... arg0) {
FTPClient client = new FTPClient();
try {
client.connect("*****");
}
catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
client.login("*****", "*****");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "/sdcard/"+userID+".task" );
}
catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
resultOk &= client.retrieveFile( userID+".task", fos );
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}/**
try {
client.deleteFile(userID+".task");
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
**/
try {
client.disconnect();
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
return null;
}
}
The Broadcastreceiver class:
public class LiveAction extends BroadcastReceiver {
...
private Context cont;
FileReader fr = null;
BufferedReader br;
#Override
public void onReceive(Context context, Intent intent)
{
cont = context;
...
new GetTask().execute();
try {
Thread.sleep(3000);
}
catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
try {
fr = new FileReader("/sdcard/"+userID+".task");
}
catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
br = new BufferedReader(fr)
String strline = "";
try {
while ((strline = br.readLine()) != null){
if(strline.equals("taskone")){
//Some GUI Tasks
}
....
This is the relevant code.
I think the best approach would be to read the file's contents from the doInBackground inside the AsyncTask and then output an object which contains the info you need on the onPostExecute method of the async stask and then manipulate your UI.
private AsyncTask<String,Void,FileInfo> getFile(){
return new AsyncTask<String,Void,FileInfo>{
protected FileInfo doInBackground(String url){
FileInfo finfo = new FileInfo(); // FileInfo is a custom object that you need to define that has all the stuff that you need from the file you just downloaded
// Fill the custom file info object with the stuff you need from the file
return finfo;
}
protected void onPostExecute(FileInfo finfo) {
// Manipulate UI with contents of file info
}
};
}
getFile().execute();
Another option is to call another AsyncTask from onPostExecute that does the file parsing but I would not recommend it
I would try some thing like this:
private class GetTask extends AsyncTask{
LiveAction liveAction;
public GetTask(LiveAction liveAction){
this.liveAction = liveAction;
}
...
#Override
protected void onPostExecute(String result) {
liveAction.heyImDoneWithdownloading();
}
}
Ps: why the Thread.sleep(5000)?
public class LiveAction extends BroadcastReceiver {
...
public void heyImDoneWithdownloading(){
//all the things you want to do on the ui thread
}
}
I have an ASP.Net 3.5 Webservice (asmx) that returns what appears to be valid JSON. I have validated the returned JSON using an online validator (JSONLint . com) and it says it is valid. I can not figure out how to parse this string.
{
"d": "{\"returnType\":\"authToken\",\"returnData\":\"b1ec28b8-3fca-427a-bbce-8802fb95d94b\"}"
}
Below is my code.
public static JSONObject DotNetJSONResponse(String raw) throws Exception {
JSONObject joRaw;
try {
joRaw = new JSONObject(raw);
JSONObject joD = joRaw.getJSONObject("d");
return joD;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
try this way
public static JSONObject DotNetJSONResponse(String raw) throws Exception {
JSONObject joRaw;
try {
joRaw = new JSONObject(raw);
String str1 = joRaw.getString("d");
JSONObject joD = new JSONObject(str1);
return joD;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
try this one. In your sample response, d is a an attribute, not a JSONObject. So have to parse the string first, then convert the d string as a JSONObject.
public static JSONObject DotNetJSONResponse(String raw) throws Exception {
JSONObject joRaw;
try {
joRaw = new JSONObject(raw);
String t=joRaw.getString("d");
System.out.println(t); \\< ----------
JSONObject joD = new JSONObject(t);
return joD;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}