我想从网页获取数据,因为我想要监控一些列车延迟(最多6个),但是当我做一个新的InputStream时应用程序崩溃了连接方法:\
这是连接方法
public class DataReader {
static URL url;
static HttpURLConnection hUC;
static InputStream inStream;
static BufferedReader br;
static String situation[];
public DataReader(int size) {
situation = new String[size];
initializeSituations(size);
}
private void initializeSituations(int size) { for (int i = 0; i < size; i ++) { situation[i] = "Not monitored";} }
public static void connect(int ind, String tNumb) throws IOException {
url = new URL("http://mobile.viaggiatreno.it/vt_pax_internet/mobile/numero?lang=EN&numeroTreno=" + tNumb);
hUC = (HttpURLConnection) url.openConnection();
inStream = new BufferedInputStream(hUC.getInputStream());
br = new BufferedReader(new InputStreamReader(inStream));
}
public static int setSituation(int ind) throws IOException {
if (readTo("\t\t\t\t<!-- SITUAZIONE -->") == 0) {
br.close();
return 0;
}
skipLine();
situation[ind] = readToBr();
br.close();
return 1;
//1 = set done
//0 = error
}
connect方法由onPreExecute方法
中的asyncTask调用public class ThreadUnit extends AsyncTask<Void, Integer, Void> {
int ind;
int j;
public ThreadUnit(int ind) {
this.ind = ind;
this.j = 0;
}
@Override
protected void onPreExecute() {
//Toast.makeText(DataHolder.context, "on pre execute", Toast.LENGTH_SHORT).show();
DataHolder.progressBars[this.ind].setProgress(0);
DataHolder.progressBars[this.ind].setMax(DataHolder.pTime[this.ind]);
try {
DataReader.connect(this.ind, DataHolder.getTrainNumber(this.ind));
DataReader.setSituation(this.ind);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected Void doInBackground(Void... voids) {
for ( this.j = 0; this.j < DataHolder.pTime[this.ind]; this.j += 1000) {
try {
Thread.sleep(1000);
publishProgress(j);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (isCancelled())
break;
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
//Toast.makeText(DataHolder.context, "onProgressUpdate!" + progress[0].toString(), Toast.LENGTH_SHORT).show();
DataHolder.progressBars[this.ind].setProgress(progress[0]);
}
@Override
protected void onPostExecute(Void aVoid) {
//Toast.makeText(DataHolder.context, "done!", Toast.LENGTH_SHORT).show();
ThreadHive.restartUnit(this.ind);
DataHolder.updateMainScreen(this.ind);
}
@Override
protected void onCancelled() {
//Toast.makeText(DataHolder.context, "cancelled!", Toast.LENGTH_SHORT).show();
DataHolder.progressBars[this.ind].setProgress(0);
}
}
这也是启动线程的方法
public void addTrain(View view) {
if (trainNumber.getText().length() == 0){
Toast.makeText(this, "Insert a train number", Toast.LENGTH_LONG).show();
return;
}
int selectedId = radioTime.getCheckedRadioButtonId();
radioTimeButton = (RadioButton) findViewById(selectedId);
int pollingValue = Integer.parseInt(radioTimeButton.getHint().toString());
int ind = getIntent().getIntExtra("index", 0);
DataHolder.setTrainNumber(ind, trainNumber.getText().toString());
DataHolder.set_tStatus(ind, randomStatus());
DataHolder.set_pStatus(ind, true);
DataHolder.set_pTime(ind, pollingValue);
ThreadHive.executeUnit(ind);
onOptionsItemSelected(null);
}
这是主要声明2个静态类和线程类。
DataHolder:只需在所有活动之间共享所有数据,并在mainAcitivity上设置更改(如更新进度条)
DataReader:设置连接并使用一些方法从页面中获取我想要的值。
ThreadHive:创建,杀死并执行有关线程的所有内容
public class MainActivity extends AppCompatActivity {
public static final int TRAIN_SLOTS = 6;
TextView[] trainNumbersTW = new TextView[TRAIN_SLOTS];
TextView[] trainTimeTW = new TextView[TRAIN_SLOTS];
LinearLayout[] linearLayouts = new LinearLayout[TRAIN_SLOTS];
ProgressBar[] progressBars = new ProgressBar[TRAIN_SLOTS];
Button[] buttons = new Button[TRAIN_SLOTS];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setIcon(R.mipmap.ic_launcher_transparent);
for (int i = 0; i < TRAIN_SLOTS; i++){
String id = "textViewTN" + (i+1);
int temp = getResources().getIdentifier(id, "id", getPackageName());
trainNumbersTW[i] = (TextView)findViewById(temp);
}
for (int i = 0; i < TRAIN_SLOTS; i++){
String id = "textViewTT" + (i+1);
int temp = getResources().getIdentifier(id, "id", getPackageName());
trainTimeTW[i] = (TextView)findViewById(temp);
}
for (int i = 0; i < TRAIN_SLOTS; i++){
String id = "line" + (i+1);
int temp = getResources().getIdentifier(id, "id", getPackageName());
linearLayouts[i] = (LinearLayout) findViewById(temp);
}
for (int i = 0; i < TRAIN_SLOTS; i++) {
String id = "updateT" + (i + 1);
int temp = getResources().getIdentifier(id, "id", getPackageName());
buttons[i] = (Button) findViewById(temp);
}
for (int i = 0; i < TRAIN_SLOTS; i++) {
String id = "progressBar" + (i + 1);
int temp = getResources().getIdentifier(id, "id", getPackageName());
progressBars[i] = (ProgressBar) findViewById(temp);
}
new DataReader(TRAIN_SLOTS);
new DataHolder(trainNumbersTW, trainTimeTW, progressBars, linearLayouts, buttons, this);
new ThreadHive(TRAIN_SLOTS);
}
/**********_START_ACTIVITIES_**********/
public void startEditActivity(View v, int ind) {
Intent intent = new Intent(MainActivity.this, EditActivity.class);
intent.putExtra("index", ind);
startActivity(intent);
}
public void startSettingActivity(View v, int ind) {
Intent intent = new Intent(MainActivity.this, EditTrainSettingsActivity.class);
intent.putExtra("index", ind);
startActivity(intent);
}
public void startPreferences(View v) {
Intent intent = new Intent(MainActivity.this, EditPreferences.class);
startActivity(intent);
}
/**********_MENU_**********/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_notifications:
if (item.isChecked()) {
item.setChecked(false);
Toast.makeText(getApplicationContext(), "Notifications disabled", Toast.LENGTH_SHORT).show();
}else {
item.setChecked(true);
Toast.makeText(getApplicationContext(), "Notifications enabled", Toast.LENGTH_SHORT).show();
}
return true;
case R.id.item_preferences:
startPreferences(getCurrentFocus());
return true;
case R.id.item_refresh:
resetToDefault();
ThreadHive.DestroyHive();
DataHolder.updateAllMainScreen();
Toast.makeText(getApplicationContext(), "Refreshed", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**********_BUTTONS_CLICKED_**********/
public void pollingStatus(View view) {
Button b = (Button)view;
int ind = getIndexLine(view);
if (DataHolder.pStatus[ind] == true) {
if(DataHolder.tStatus[ind]!=-1) {
DataHolder.set_tStatus(ind, 0);
ThreadHive.killUnit(ind);
}
DataHolder.set_pStatus(ind, false);
b.setText("STOP");
}else{
if(DataHolder.tStatus[ind]!=-1) {
DataHolder.set_tStatus(ind, randomState());
ThreadHive.executeUnit(ind);
}
DataHolder.set_pStatus(ind, true);
b.setText("START");
}
DataHolder.updateMainScreen(ind);
}
public void editTrain(View view) {
int ind = getIndexLine(view);
if (DataHolder.tStatus[ind] == -1) {
DataHolder.tStatus[ind] = randomState();
startEditActivity(view, ind);
}else
startSettingActivity(view, ind);
DataHolder.updateMainScreen(ind);
}
这是我得到的错误曲目。
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:21169)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:21169)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
at java.net.InetAddress.lookupHostByName(InetAddress.java:431)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at com.android.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:188)
at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:157)
at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:100)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:358)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:331)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:249)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at com.teocri.trainmonitor.DataReader.connect(DataReader.java:31)
at com.teocri.trainmonitor.ThreadUnit.onPreExecute(ThreadUnit.java:25)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:604)
at com.teocri.trainmonitor.ThreadHive.executeUnit(ThreadHive.java:31)
at com.teocri.trainmonitor.EditActivity.addTrain(EditActivity.java:58)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5210)
at android.view.View$PerformClick.run(View.java:21169)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
在添加connect方法之前一切正常,所以我想这是问题,但我不知道如何修复它。
非常感谢你的帮助!
答案 0 :(得分:0)
在此处发布问题之前请先查看您的logcat
android.os.NetworkOnMainThreadException
这意味着你在主线程上做了一些网络任务。找到并解决它。
答案 1 :(得分:0)
也许您的设备中有完整的内存,因此线程无法分配内存并崩溃