我得到了一个AsyncTask,应该检查对主机名的网络访问。但是doInBackground()永远不会超时。有人知道吗?
public class HostAvailabilityTask extends AsyncTask<String, Void, Boolean> {
private Main main;
public HostAvailabilityTask(Main main) {
this.main = main;
}
protected Boolean doInBackground(String... params) {
Main.Log("doInBackground() isHostAvailable():"+params[0]);
try {
return InetAddress.getByName(params[0]).isReachable(30);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean... result) {
Main.Log("onPostExecute()");
if(result[0] == false) {
main.setContentView(R.layout.splash);
return;
}
main.continueAfterHostCheck();
}
}
如果你正在使用Firebase,你可以使用这个。
Java:
DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
Log.d(TAG, "connected");
} else {
Log.d(TAG, "not connected");
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
Log.w(TAG, "Listener was cancelled");
}
});
科特林:
val connectedRef = Firebase.database.getReference(".info/connected")
connectedRef.addValueEventListener(object : ValueEventListener {
override fun onDataChange(snapshot: DataSnapshot) {
val connected = snapshot.getValue(Boolean::class.java) ?: false
if (connected) {
Log.d(TAG, "connected")
} else {
Log.d(TAG, "not connected")
}
}
override fun onCancelled(error: DatabaseError) {
Log.w(TAG, "Listener was cancelled")
}
})
这个线程中的大多数答案只检查是否有可用的连接,但不检查该连接是否工作,其他答案不是设备范围,我的解决方案应该在每个设备上工作。
你可以在启动应用程序之前在你的主要活动中删除我的代码,它会快速确定是否有实际的互联网连接,如果有对话框将立即删除,应用程序将被启动,如果没有警报会弹出说应用程序需要互联网连接才能工作。
final AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Checking Connection");
alertDialog.setMessage("Checking...");
alertDialog.show();
new CountDownTimer(5000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
new Thread(new Runnable() {
public void run() {
try {
URL url = new URL("http://web.mit.edu/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
isConnected = connection.getResponseCode() == HttpURLConnection.HTTP_OK;
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
if (isConnected == false){
alertDialog.setMessage("Try " + (5 - millisUntilFinished/1000) + " of 5.");
} else {
alertDialog.dismiss();
}
}
@Override
public void onFinish() {
if (isConnected == false) {
alertDialog.dismiss();
new AlertDialog.Builder(activity)
.setTitle("No Internet")
.setMessage("Please connect to Internet first.")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// kill the app?
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
} else {
// Launch the app
}
}
}.start();
Kotlin和协程
我将函数放置在一个ViewModel中,该ViewModel具有viewModelScope。使用一个可观察的LiveData,我通知一个活动有关连接。
ViewModel
fun checkInternetConnection(timeoutMs: Int) {
viewModelScope.launch(Dispatchers.IO) {
try {
val socket = Socket()
val socketAddress = InetSocketAddress("8.8.8.8", 53)
socket.connect(socketAddress, timeoutMs)
socket.close()
_connection.postValue(true)
}
catch(ex: IOException) {
_connection.postValue(false)
}
}
}
private val _connection = MutableLiveData<Boolean>()
val connection: LiveData<Boolean> = _connection
活动
private fun checkInternetConnection() {
viewModel.connection.observe(this) { hasInternet ->
if(!hasInternet) {
//hasn't connection
}
else {
//has connection
}
}
}
下面是一些现代代码,使用AsynTask来解决android崩溃的问题,当你尝试在主线程上连接并为用户引入一个带有冲洗和重复选项的警报。
class TestInternet extends AsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... params) {
try {
URL url = new URL("http://www.google.com");
HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
urlc.setConnectTimeout(3000);
urlc.connect();
if (urlc.getResponseCode() == 200) {
return true;
}
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
if (!result) { // code if not connected
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage("An internet connection is required.");
builder.setCancelable(false);
builder.setPositiveButton(
"TRY AGAIN",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
new TestInternet().execute();
}
});
AlertDialog alert11 = builder.create();
alert11.show();
} else { // code if connected
doMyStuff();
}
}
}
...
new TestInternet().execute();