我创建了一个分为两部分的应用程序android:T
使用Jsoup.connect()
并与AsyncTask
关联的管理员和所有替代方法在站点上进行呼叫。
使用管理器调用方法并设置答案格式的活动。
我的问题是当我尝试在一个活动中接听电话时。用户界面将一直处于阻塞状态,直到电话应答为止。
在阅读StackOverflow中的其他问题时,我了解到问题是当我尝试使用Jsoup.connect(values[0]).get();
方法调用doInBackground()
时,但是我尝试遵循一些指南,但是没有人可以使用
代码
活动
public class CreazioneLibrettoActivity extends AppCompatActivity {
private EditText editMatricola;
private Spinner elencoPercorsi;
private ListView elencoInsegnamenti;
private String matricola;
private PercorsiAdapter percorsiAdapter;
private InsegnamentiAdapter insegnamentiAdapter;
private ArrayList<Insegnamento> elencoEsami;
private FloatingActionButton bottonPiano;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_creazione_libretto);
bottonPiano = findViewById(R.id.bottonPiano);
editMatricola = findViewById(R.id.matricola);
elencoPercorsi = findViewById(R.id.elencoPercorsi);
elencoInsegnamenti = findViewById(R.id.elencoInsegnamenti);
editMatricola.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(charSequence.length() == 5) {
InputMethodManager imm = (InputMethodManager)getSystemService(getApplicationContext().INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editMatricola.getWindowToken(), 0);
Esse3RecoveryManager esse3 = new Esse3RecoveryManager(getApplicationContext());
matricola = charSequence.toString();
String result = esse3.selectCdL(matricola);
if(result != null) {
if(result.equals("nullo")){
Toast.makeText(getApplicationContext(),"Nessuna connessione a internet",Toast.LENGTH_LONG).show();
}
else
{
TreeMap<String, String> percorsi = esse3.getPercorsi(result);
if(percorsi == null) {
System.out.println(percorsi);
Toast.makeText(getApplicationContext(),"Nessuna connessione a internet",Toast.LENGTH_LONG).show();
} else {
percorsiAdapter = new PercorsiAdapter(getApplicationContext(), R.layout.spinner_percorsi, percorsi);
elencoPercorsi.setAdapter(percorsiAdapter);
elencoPercorsi.setVisibility(View.VISIBLE);
}
}
} else {
Toast.makeText(getApplicationContext(),"Matricola non trovata",Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
elencoPercorsi.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String url = view.getTag().toString();
if(!url.equals("firstTag")) {
Esse3RecoveryManager esse3 = new Esse3RecoveryManager(getApplicationContext());
elencoEsami = esse3.getCdS(url, matricola);
if (elencoEsami == null) {
Toast.makeText(getApplicationContext(), "Nessuna connessione a internet", Toast.LENGTH_LONG).show();
} else {
insegnamentiAdapter = new InsegnamentiAdapter(getApplicationContext(), R.layout.insegnamenti_listview, elencoEsami);
elencoInsegnamenti.setAdapter(insegnamentiAdapter);
elencoInsegnamenti.setVisibility(View.VISIBLE);
bottonPiano.setVisibility(View.VISIBLE);
}
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
bottonPiano.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(), PianoActivity.class);
i.putExtra("matricola", matricola);
i.putExtra("elencoEsami", elencoEsami);
startActivity(i);
}
});
}
}
AsyncTask
public class Esse3RecoveryManager{
private Context context;
private static Document docInitial = null;
private static final String URL_SELECT_CDL = "https://esse3web.unisa.it/Guide/ListaFacoltaCorsi.do";
public Esse3RecoveryManager(Context context) {
this.context = context;
}
/**
* Metodo utilizzato per il recupero dell'url del sito web del corso di laurea scelto dall'utente.
* @param matricola, la matricola del corso di laurea scelto dall'utente.
* @return l'url del corso di laurea.
*/
public String selectCdL(String matricola) {
if(!networkConnectivity() || !isInternetWorking(URL_SELECT_CDL)) {
return "nullo";
}
if(docInitial == null) {
try {
NetworkTask nt = new NetworkTask();
docInitial = nt.execute(URL_SELECT_CDL).get();
} catch (Exception e) {
e.getMessage();
}
}
Document doc = docInitial;
Element a;
if(doc.select("a:contains("+ matricola + ")").size() > 0)
{
a = doc.select("a:contains("+ matricola + ")").get(0);
return "https://esse3web.unisa.it/" + a.attr("href");
}
return null;
}
/**
* Metodo utilizzato per il recupero dei percorsi di studio relativi al corso di laurea scelto dall'utente.
* @param url, l'url relativo al corso di laurea scelto dall'utente.
* @return l'elenco dei percorsi di studio.
*/
public TreeMap<String, String> getPercorsi(String url) {
if(!networkConnectivity() || !isInternetWorking(url)) {
return null;
}
NetworkTask nt = new NetworkTask();
Document doc = null;
try {
doc = nt.execute(url).get();
} catch (Exception e) {
e.printStackTrace();
}
Elements links_percorso = doc.select("a:contains(Ord.)");
TreeMap<String, String> percorsi = new TreeMap<String, String>();
percorsi.put("- - - Scegli il percorso di studi - - -","firstTag");
for(Element link : links_percorso) {
percorsi.put(link.text(), "https://esse3web.unisa.it/" + link.attr("href"));
}
return percorsi;
}
/**
* Metodo utilizzato per il recupero della durata del CdL.
* @param url, l'url del corso di laurea scelto dall'utente.
* @return la durata del CdL.
*/
public int durataCdL(String url) {
NetworkTask nt = new NetworkTask();
Document doc = null;
try {
doc = nt.execute(url).get();
} catch (Exception e) {
e.printStackTrace();
}
int durata = Integer.parseInt(doc.getElementsByTag("durata_effettiva").first().text());
return durata;
}
/**
* Metodo utilizzato per il recupero degli insegnamenti relativi al percorso di studi scelto.
* @param url, l'url relativo all'elenco degli insegnamenti.
* @param matricola, la matricola del corso di laurea scelto dall'utente.
* @return l'elenco degli insegnamenti.
*/
public ArrayList<Insegnamento> getCdS(String url, String matricola) {
if(!networkConnectivity() || !isInternetWorking(url)) {
return null;
}
NetworkTask nt = new NetworkTask();
Document doc = null;
try {
doc = nt.execute(url).get();
} catch (Exception e) {
e.printStackTrace();
}
int durata = durataCdL(selectCdL(matricola));
ArrayList<Insegnamento> insegnamenti = new ArrayList<Insegnamento>();
long in = System.currentTimeMillis();
for(int i=1; i<=durata; i++) {
Element table = doc.getElementById("table1_" + i);
Element tbody = table.getElementsByTag("tbody").first();
Elements rows = tbody.children();
for(Element row : rows) {
Insegnamento ins = new Insegnamento();
Elements data = row.getElementsByTag("td");
Pattern pattern = Pattern.compile("\\[(.*?)\\]");
Matcher matcher = pattern.matcher(data.get(0).text());
if (matcher.find()) {
ins.setAd_insegnamento(matcher.group(1));
}
ins.setNome_insegnamento(data.get(0).text().substring(13));
if(data.get(1).text().equals("S"))
ins.setObbligatorieta(true);
else ins.setObbligatorieta(false);
if(data.get(2).text().equals("PRIMO SEMESTRE"))
ins.setSemestre(1);
else ins.setSemestre(2);
ins.setCfu(Integer.parseInt(data.get(3).text()));
ins.setSsd(data.get(4).text());
ins.setTaf(data.get(5).text());
ins.setAnno(i);
insegnamenti.add(ins);
}
}
long out = System.currentTimeMillis();
return insegnamenti;
}
class NetworkTask extends AsyncTask<String, Integer, Document> {
@Override
protected Document doInBackground(String... values) {
try {
Document doc = Jsoup.connect(values[0]).get();
return doc;
} catch (IOException exception) {
exception.printStackTrace();
}
return null;
}
}
class NetworkTaskInternet extends AsyncTask<String, Integer, Boolean> {
@Override
protected Boolean doInBackground(String... values) {
boolean success = false;
try {
URL url = new URL(values[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.connect();
success = connection.getResponseCode() == 200;
} catch (IOException exception) {
exception.printStackTrace();
}
return success;
}
}
public boolean isInternetWorking(String url) {
NetworkTaskInternet nti = new NetworkTaskInternet();
boolean success = false;
try {
success = nti.execute(url).get();
} catch (Exception e) {
e.printStackTrace();
}
return success;
}
private boolean networkConnectivity() {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
}
return false;
}
}
答案 0 :(得分:1)
这是因为您要在AsyncTask上调用get()
。有效地使其变得无用,因为它在继续之前等待AsyncTask完成。
请使用回调。制作一个简单的界面:
interface NetworkCallback {
void onDocumentLoaded(Document document);
}
然后将其添加为AsyncTask构造函数的参数,并将其分配给全局变量:
class NetworkTask extends AsyncTask<String, Integer, Document> {
private NetworkCallback callback;
public NetworkTask(NetworkCallback callback) {
this.callback = callback;
}
}
然后在onPostExecute()
中调用该侦听器:
class NetworkTask extends AsyncTask<String, Integer, Document> {
private NetworkCallback callback;
public NetworkTask(NetworkCallback callback) {
this.callback = callback;
}
// your doInBackground logic
@Override
protected void onPostExecute(Document document) {
callback.onDocumentLoaded(document);
}
}
现在,当您创建NetworkTask的新实例时,它应如下所示:
new NetworkTask(new NetworkCallback() {
@Override
public void onDocumentLoaded(Document document) {
//do whatever you want to do with the document
}).execute(url);
我建议您对所有AsyncTask执行此操作。您只需要为每个接口创建一个适当的回调接口。
此外,将您的AsyncTasks设为静态:
static class NetworkTask extends AsyncTask<String, Integer, Document>