我需要从url加载文本文件并将加载的数据写入String变量。我尝试了很多例子,但我没有任何想法来解决这个简单的问题。我使用min SDK 9和目标SDK版本23.在明星应用程序上的这个代码我有信息'对不起,但你的应用程序已停止'。
public String GetVersionApk(String addres) {
URL url;
InputStream is = null;
DataInputStream dis;
int line;
StringBuilder x = new StringBuilder();
byte[] bytes = new byte[1000];
try {
url = new URL(addres);
is = url.openStream(); // throws an IOException
dis = new DataInputStream(new BufferedInputStream(is));
while ((line = dis.read(bytes)) >= 0) {
x.append(new String(bytes, 0, line));
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
is.close();
} catch (IOException ioe) {
}
}
return x.toString();
}
Log cat:
java.lang.RuntimeException:无法启动活动 ComponentInfo {} com.example.piotr.gm/com.example.piotr.gm.MapsActivity: java.lang.NullPointerException:尝试调用虚方法'void 关于空对象引用的java.io.InputStream.close()' 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2370) 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432) 在android.app.ActivityThread.access $ 900(ActivityThread.java:154) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1321) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:135) 在android.app.ActivityThread.main(ActivityThread.java:5310) at java.lang.reflect.Method.invoke(Native Method) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:904) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 引发者:java.lang.NullPointerException:尝试在空对象上调用虚方法'void java.io.InputStream.close()' 参考 在com.example.piotr.gm.MapsActivity.GetVersionApk(MapsActivity.java:67) 在com.example.piotr.gm.MapsActivity.onCreate(MapsActivity.java:83) 在android.app.Activity.performCreate(Activity.java:6865) 在android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106) 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2323) 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2432) 在android.app.ActivityThread.access $ 900(ActivityThread.java:154) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1321) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:135) 在android.app.ActivityThread.main(ActivityThread.java:5310) at java.lang.reflect.Method.invoke(Native Method) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:904) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
编辑[22.10.2015]: 我更新了我的函数,因为我发现,该函数必须在AsyncTask中运行
private class GetVersionApk extends AsyncTask<String,String,String> {
public AsyncResponse delegate = null;
protected String doInBackground(String... urls) {
URL url;
InputStream is = null;
DataInputStream dis;
int line;
StringBuilder x = new StringBuilder();
byte[] bytes = new byte[1000];
try {
url = new URL(urls[0]);
is = url.openStream(); // throws an IOException
dis = new DataInputStream(new BufferedInputStream(is));
while ((line = dis.read(bytes)) >= 0) {
x.append(new String(bytes, 0, line));
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try{
is.close();
} catch (IOException ioe) {
}
}
return x.toString();
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
Log.i("Version APK SERVER", String.valueOf(new GetVersionApk().execute("http://url.example.com/update.php")));
//setUpMapIfNeeded();
}
在控制台日志中我修改:
版本APK SERVER:com.example.piotr.gm.MapsActivity$GetVersionApk@24ed514e
在服务器文件返回文本:1akkkk
我知道,我必须在此函数中返回结果,但是如何?
protected void onPostExecute(String result) {
delegate.processFinish(result);
}
答案 0 :(得分:0)
您应该执行以下操作,并且只有在InputStream
不为空时才尝试关闭。
try {
if(is != null) {
is.close();
}
} catch (IOException ioe) {
}
答案 1 :(得分:0)
尝试至少从asynctask或其他线程调用该方法。
更新:
public interface OnCallFinish {
void processFinish(String output);
}
private class GetVersionApk extends AsyncTask<String,String,String> {
private OnCallFinish finished;
public AsyncResponse delegate = null;
public GetVersionApk(OnCallFinish finished){
this.finished = finished;
}
protected String doInBackground(String... urls) {
URL url;
InputStream is = null;
DataInputStream dis;
int line;
StringBuilder x = new StringBuilder();
byte[] bytes = new byte[1000];
try {
url = new URL(urls[0]);
is = url.openStream(); // throws an IOException
dis = new DataInputStream(new BufferedInputStream(is));
while ((line = dis.read(bytes)) >= 0) {
x.append(new String(bytes, 0, line));
}
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try{
is.close();
} catch (IOException ioe) {
}
}
return x.toString();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
finished.processFinish(s);
}
}
最后,在您的主线程-onCreate中 - 只需将其称为:
new GetVersionApk(new Connection.OnCallFinish() {
@Override
public void processFinish(String output){
//WRITE YOUR OWN CODE
}}).execute();
你可能会有一些编译问题,因为我想知道,如果是这样,请告诉我。