I use the code below which in my http get request,but what I get from return is a null.I don't know why.
public static String getResponseFromGetUrl(String url) throws Exception {
StringBuffer sb = new StringBuffer();
try {
HttpResponse httpResponse = httpclient.execute(httpRequest);
String inputLine = "";
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
InputStreamReader is = new InputStreamReader(httpResponse
.getEntity().getContent());
BufferedReader in = new BufferedReader(is);
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
in.close();
}
} catch (Exception e) {
e.printStackTrace();
return "net_error";
} finally {
httpclient.getConnectionManager().shutdown();
}
return sb.toString();
}
And what I have use the function is
String json_str = HttpUtils.getResponseFromGetUrl("www.xxx.com/start");
if ((json_str == null)) Log.d("Chen", "lastestTimestap----" + "json_str == null");
And sometimes the Log will be printed.Not always,in fact like 1%.But I don't know why it caused.
This code will not produce a "null". There must be more code you are not showing.
If this is all the code you have I suggest you remove the StringBuffer and replace it with
return "";
More likely you have forgetten to mention some code which is doing something like
Object o = null;
sb.append(o); // appears as "null"
EDIT: Based on your update, I would have to assume you are reading a line like "null"
It is highly unlikely you want to discard the newline between each line. I suggest either you append("\n") as well or just record all the text you get without regard for new lines.
BTW Please don't use StringBuffer as its replacement StringBuilder has been around for almost ten years. There is a common misconception that using StringBuffer helps with multi-threading but more often it results in incorrect code because it is very harder, if not impossible to use StringBuffer correctly in a multi-threaded context
Related
My code is too slow
How can I make my code efficiently? Currently the code needs several minutes until the file was read, which is way too long. Can this be done faster? There is no stacktrace, because it works, but too slow.
Thanks!
The Problem Code:
private void list(){
String strLine2="";
wwwdf2 = new StringBuffer();
InputStream fis2 = this.getResources().openRawResource(R.raw.list);
BufferedReader br2 = new BufferedReader(new InputStreamReader(fis2));
if(fis2 != null) {
try {
LineNumberReader lnr = new LineNumberReader(br2);
String linenumber = String.valueOf(lnr);
int i=0;
while (i!=1) {
strLine2 = br2.readLine();
wwwdf2.append(strLine2 + "\n");
String contains = String.valueOf(wwwdf2);
if(contains.contains("itisdonecomplet")){
i++;
}
}
// Toast.makeText(getApplicationContext(), strLine2, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), wwwdf2, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Use StringBuilder instead of StringBuffer.
StringBuffer is synchronized, and you don't need that.
Don't use String.valueOf, which builds a string, negating the value using a StringBuffer/Builder. You are building a string from the whole buffer, checking it, discarding the string, then constructing nearly the same string again.
Use if (wwwdf2.indexOf("itisdonecomplet") >= 0) instead, which avoids creating the string.
But this will still be reasonably slow, as although you would not be constructing a string and searching through it all, you are still doing the searching.
You can make this a lot faster by only searching the very end of the string. For example, you could use wwwdf2.indexOf("itisdonecomplet", Math.max(0, wwwdf2.length() - strLine2.length() - "itisdonecomplet".length())).
Although, as blackapps points out in a comment, you could simply check if strLine2 contains that string.
Don't use string concatenation inside a call to append: make two separate calls.
wwwdf2.append(strLine2);
wwwdf2.append("\n");
You don't check if you reach the end of the file. Check if strLine2 is null, and break the loop if it is.
My new Created code:(My test device is a Samsung S8)
private void list(){
String strLine2="";
wwwdf2 = new StringBuilder();
InputStream fis2 = this.getResources().openRawResource(R.raw.list);
BufferedReader br2 = new BufferedReader(new InputStreamReader(fis2));
if(fis2 != null) {
try {
LineNumberReader lnr = new LineNumberReader(br2);
String linenumber = String.valueOf(lnr);
int i=0;
while (i!=1) {
strLine2 = br2.readLine();
wwwdf2.append(strLine2);
wwwdf2.append("\n");
if (wwwdf2.indexOf("itisdonecomplet") >= 0){
i++;
}
}
// Toast.makeText(getApplicationContext(), strLine2, Toast.LENGTH_LONG).show();
Toast.makeText(getApplicationContext(), wwwdf2, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I am trying to figure out how to display 🔴 in java. I am able to convert unicode to show so if I could convert 🔴to unicode then I would be set. I was thinking I could just make a big check list but figure that would cause alot of strain to check.
I am trying to show 🔴, but the API call gives me 🔴. My question is, how do I change 🔴 to the red circle other then finding the Unicode string for it.
This is what the symbol looks like 🔴
Code to format json
private static String getStringFromInputStream(InputStream is) {
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
String line;
try {
br = new BufferedReader(new InputStreamReader(is));
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}
It looks like you're looking at the characters with an editor in which you haven't specified the correct character encoding / set.
To use smybol that String in Java, try:
String text = "\uD83D\uDD34";
JLabel label = new JLabel(text);
Source of the unicode escapes: https://www.htmlsymbols.xyz/unicode/U+1F534
(It may still be that your font doesn't have the character, in which case it will probably look like a question mark - better than 4 strange accented characters, probably)
There still remains one problem: new InputStreamReader(is) uses the default encoding the program runs on. I would expect the fixed encoding of the is: new InputStreamReader(is, "UTF-8")
So we are working on this app in Android Studio where we want to make a get request to a website, and when we run this piece of code, we keep getting an error of "null" which I believe to be so because one of the variables in this piece of code is null. Can someone look it over and see any places where you may detect some variable is not being used correctly and therefore providing a null error?
public class SpotAlgo {
String vidLink;
int linkLoc;
String testString = "<title>";
String result;
public String gettheResult(String v) throws Exception{
String sname = " ";
vidLink = "https://open.spotify.com/track/43PuMrRfbyyuz4QpZ3oAwN";
URL obj = new URL(vidLink);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine = "";
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
result = response.toString();
linkLoc = result.indexOf(testString) + testString.length();
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sname += result.charAt(i) + "";
}
return obj.toString();
}
}
Nothing, it works fine!
I believe that if you have a null pointer exception, it is related to another part of your code.
However, here are some suggestions to improve it
In this snippet you add text to the sname variable in a loop. When you do that kind of operation a StringBuilder will be more efficient.
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sname += result.charAt(i) + "";
}
//Could be replaced b
for (int i = linkLoc; i < result.indexOf("on Spotify"); i++) {
sb.append(result.charAt(i));
}
You can later use sb.toString() to get the result of the operation.
Also, more importantly, when you do network operation you never know what the result will be. There can be many variables that will inpact the result you will get, and often exceptions will be thrown. It is important that you wrap the network code in a try { } finally {}, and that you close the ressources you open in the finally block (a finally block always execute).
edit
Fixed a typo
edit 2
Some people are saying it is throwing a 404 exception, I did not get one when I ran it on my machine, and a 404 would throw an IOException when you do con.getInputStream(), so you would likely see that instead
You missed actually connecting
con.setRequestMethod("GET");
con.connect();
Your con.getInputStream(); is null since the connection is not made and nothing is returned to con.
I am using the following code to get data from a file
try {
InputStreamReader inputStreamReader = new InputStreamReader(openFileInput(TEXTFILE));
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String string;
StringBuilder stringbuilder = new StringBuilder();
while ((string=bufferedReader.readLine())!=null){
stringbuilder.append(string);
}
EditText.setText(stringbuilder.toString());
} catch (Exception e) {
e.printStackTrace();
}
It works but
when I put the string=bufferedReader.readLine() before While, I get an exception : java.lang.OutOfMemoryError
You're reading a line from the BufferedReader, and storing the result in string. After that, you check if string != null, and if not, you append string to stringbuilder. You're repeating this until string == null.
The confusion here might be the comparison of an assignment statement:
while ((string = bufferedReader.readLine()) != null) { ... }
This is a short notation of the following:
string = bufferedReader.readLine();
while (string != null) {
...
string = bufferedReader.readLine();
}
I am doing my first Android app and I have to take the code of a html page.
Actually I am doing this:
private class NetworkOperation extends AsyncTask<Void, Void, String > {
protected String doInBackground(Void... params) {
try {
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
String inputLine;
String s1 = "";
while ((inputLine = in.readLine()) != null)
s1 = s1 + inputLine;
in.close();
//return
return s1;
}
catch (IOException e) {
e.printStackTrace();
}
return null;
}
but the problem is it takes too much time. How to take for exemple the HTML from the line 200 to the line 300 ?
Sorry for my bad english :$
Best case use instead of readLine() use read(char[] cbuf, int off, int len). Another dirty way
int i =0;
while(while ((inputLine = in.readLine()) != null)
i++;
if(i>200 || i<300 )
DO SOMETHING
in.close();)
You get the HTML document through HTTP. HTTP usually relies on TCP. So... you can't just "skip lines"! The server will always try to send you all data preceding the portion of your interest, and your side of communication must acknowledge the reception of such data.
Do not read line by line [use read(char[] cbuf, int off, int len)]
Do not concat Strings [use a StringBuilder]
Open The buffered reader (much like you already do):
URL oracle = new URL("http://www.nationalleague.ch/NL/fr/");
BufferedReader in = new BufferedReader(new InputStreamReader(oracle.openStream()));
Instead of reading line by line, read in a char[] (I would use one of size about 8192)
and than use a StringBuilder to append all the read chars.
Reading secific lines of HTML-source seams a little risky because formatting of the source code of the HTML page may change.