Inet Address Library Shows: Java Android Studio 应用程序上的主线程错误

huangapple go评论67阅读模式
英文:

Inet Adress Library Shows: Main Thread Error On Java Android Studio App

问题

以下是翻译好的部分:

我一直在创建一个关于检查 x 网站 IP 的应用程序,我已经导入了 java.net.InetAddress 并且它可以在 IntelliJ 上运行,但是在 Android Studio 上,try/catch 块捕获到了一些错误:android.os.NetworkOnMainThreadException。所以这是代码部分:

AsyncTask.execute(new Runnable() {
@Override
public void run() {
submit.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            InetAddress address = null;
            try {
                address = InetAddress.getByName(String.valueOf(hostnumber));
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }catch (Exception e) {
                Toast.makeText(Lookup.this,"Problem"+e, Toast.LENGTH_SHORT).show();
            }

            output.setText((CharSequence) address);


        }
    });

}

});

我已经在清单文件中添加了互联网权限:

try/catch 块捕获到了 'android.os.NetworkOnMainThreadException' 错误。

我看到一些来自 Stack Overflow 的答案,例如:https://stackoverflow.com/questions/6343166/how-to-fix-android-os-networkonmainthreadexception,https://www.tutorialspoint.com/how-to-fix-android-os-networkonmainthreadexception

但仍然无法显示网站的 IP 并再次显示错误。如果您有任何解决这个问题的方法,请告诉我。提前感谢!

更新:我尝试添加了一个布尔语句,但它使情况变得更糟,引发了更多错误。也许语法这些块的格式不正确?我应该在哪里修复这段代码?

英文:

I've Been creating an app about checking the ip of x websites and I've imported:java.net.InetAddress and It will work on intelij but on android studio the try/catch block catches some errors: android.os.NetworkOnMainThreadException. So this the code part:

   AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                submit.setOnClickListener(new View.OnClickListener() {
    
                    @Override
                    public void onClick(View v) {
    
                        InetAddress address = null;
                        try {
                            address = InetAddress.getByName(String.valueOf(hostnumber));
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }catch (Exception e) {
                            Toast.makeText(Lookup.this,"Problem"+e, Toast.LENGTH_SHORT).show();
                        }
    
                        output.setText((CharSequence) address);
    

                    }
                });
    
            }
        });


I've added the internet permission on manifest: <uses-permission android:name="android.permission.INTERNET" />

The try/catch block caught: 'android.os.NetworkOnMainThreadException'

I saw some answers from stack such as: https://stackoverflow.com/questions/6343166/how-to-fix-android-os-networkonmainthreadexception , https://www.tutorialspoint.com/how-to-fix-android-os-networkonmainthreadexception

....

BUT still it wouldn't show the IPs of the websites and show the error again. If you have any solution to this problem please lmk. Thanks In Advance!

UPDATE: I tried to put a boolean statement but it made it even worse throwing some more errors. Is maybe the wrong format to syntax these blocks? where should I fix the code?

答案1

得分: 1

您遇到问题是因为在Android中,您只能在主线程中访问视图(View),而只能在工作线程(WorkerThread)中访问网络。此外,您创建AsyncTask的方式不正确。

我已经完全转向了Kotlin几年前,已经有3年没有编写Java代码了,但以下代码应该可以工作:

public class Testss extends Activity {
    static class Result<T> {
        static class Success<T> extends Result<T> {
            public T data;

            public Success(T data) {
                this.data = data;
            }
        }

        static class Failure<T> extends Result<T> {
            public Throwable error;

            public Failure(Throwable error) {
                this.error = error;
            }
        }
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ...

        submit.setOnClickListener(new View.OnClickListener() {
            AsyncTask<String, Void, Result<InetAddress>> task = new AsyncTask<String, Void, Result<InetAddress>>() {
                // 注意:此方法在后台线程中运行,不能从这里访问视图
                @Override
                protected Result<InetAddress> doInBackground(String... hostnumber) {
                    Result<InetAddress> result;
                    try {
                        result = new Result.Success(InetAddress.getByName(String.valueOf(hostnumber[0])));
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                        result = new Result.Failure(e);
                    } catch (Exception e) {
                        result = new Result.Failure(e);
                    }

                    return result;
                }

                // 注意:此方法在主线程中运行
                @Override
                protected void onPostExecute(Result<InetAddress> result) {
                    if (result instanceof Result.Success) {
                        output.setText(((Result.Success<InetAddress>) result).data.toString());
                    } else if (result instanceof Result.Failure) {
                        Throwable error = ((Result.Failure<InetAddress>) result).error;
                        Toast.makeText(Testss.this, "Problem" + error, Toast.LENGTH_SHORT).show();
                    }
                }
            };

            task.execute(hostnumber);
        });
    }
}

请注意,我在代码中进行了一些修正,以确保它能够正确运行。希望这可以解决您的问题。

英文:

You're having issues because in Android you can only access the View in the MainThread and you can only access the Network in a WorkerThread.

Also the way you're creating the AsyncTask is not correct.

I've fully switched to Kotlin years ago, and I don't write Java for a good 3 years, this however should work:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-java -->

public class Testss extends Activity {
static class Result&lt;T&gt; {
static class Success&lt;T&gt; extends Result&lt;T&gt; {
public T data;
public Success(T data) {
this.data = data;
}
}
static class Failure&lt;T&gt; extends Result&lt;T&gt; {
public Throwable error;
public Failure(Throwable error) {
this.error = error;
}
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
submit.setOnClickListener(new View.OnClickListener() {
AsyncTask&lt;String, Void, Result&lt;InetAddress&gt;&gt; task = new AsyncTask&lt;String, Void, Result&lt;InetAddress&gt;&gt;() {
// NOTE: this method runs in a background thread, you cannot access the View from here
@Override
protected Result&lt;InetAddress&gt; doInBackground(String... hostnumber) {
Result&lt;InetAddress&gt; result;
try {
result = new Result.Success(InetAddress.getByName(String.valueOf(hostnumber)));
} catch (UnknownHostException e) {
e.printStackTrace();
result = new Result.Failure(e);
}catch (Exception e) {
result = new Result.Failure(e);
}
return result;
}
// NOTE: this method runs in the mainthread
@Override
protected void onPostExecute(Result&lt;InetAddress&gt; result) {
if (result instanceof Result.Success) {
output.setText((CharSequence) ((Result.Success&lt;InetAddress&gt;) result).data);
} else if (result instanceof Result.Failure) {
Throwable error = ((Result.Failure&lt;InetAddress&gt;) result).error
Toast.makeText(Lookup.this,&quot;Problem&quot;+error, Toast.LENGTH_SHORT).show();
}
}
};
task.execute(hostnumber);
};
}
}

<!-- end snippet -->

答案2

得分: 0

Hi,我已经按照Andre的建议进行了操作,这在一定程度上解决了问题,以下是相关的代码:

EditText hostnumber;
TextView output;
Button submit;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lookup);

    hostnumber = findViewById(R.id.hostnumber);
    output = findViewById(R.id.output);
    submit = findViewById(R.id.submit);
    submit.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            @SuppressLint("StaticFieldLeak") AsyncTask<String, Void, connection.Result<InetAddress>> task = new AsyncTask<String, Void, connection.Result<InetAddress>>() {
                // 注意:此方法在后台线程中运行,无法从此处访问View
                @Override
                protected connection.Result<InetAddress> doInBackground(String... hostnumber) {
                    connection.Result<InetAddress> result;
                    try {
                        result = new connection.Result.Success(InetAddress.getByName(String.valueOf(hostnumber)));
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                        result = new connection.Result.Failure(e);
                    } catch (Exception e) {
                        result = new connection.Result.Failure(e);
                    }

                    return result;
                }

                @Override
                protected void onPostExecute(connection.Result<InetAddress> result) {
                    if (result instanceof connection.Result.Success) {
                        output.setText((CharSequence) ((connection.Result.Success<InetAddress>) result).data);
                    } else if (result instanceof connection.Result.Failure) {
                        Throwable error = ((connection.Result.Failure<InetAddress>) result).error;
                        Toast.makeText(Lookup.this, "请检查地址!: " + error, Toast.LENGTH_SHORT).show();
                    }
                }
            };

            task.execute(hostnumber.toString());
        }
    });
}

这是XML文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Lookup">

    <EditText
        android:id="@+id/hostnumber"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="98dp"
        android:ems="10"
        android:inputType="textUri|textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/submit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="61dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/hostnumber" />

    <TextView
        android:id="@+id/output"
        android:layout_width="100dp"
        android:layout_height="47dp"
        android:layout_marginStart="63dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="312dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.186"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/submit" />

</androidx.constraintlayout.widget.ConstraintLayout>

我仍然面临着与这个类有关的问题。如果您有任何想法或者我做错了什么,请告诉我,谢谢!

英文:

Hi I did this as Andre suggested and it kinda solved the problem and the code:

        EditText hostnumber;
TextView output;
Button submit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lookup);
hostnumber = findViewById(R.id.hostnumber);
output = findViewById(R.id.output);
submit = findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@SuppressLint(&quot;StaticFieldLeak&quot;) AsyncTask&lt;String, Void, connection.Result&lt;InetAddress&gt;&gt; task = new AsyncTask&lt;String, Void, connection.Result&lt;InetAddress&gt;&gt;() {
// NOTE: this method runs in a background thread, you cannot access the View from here
@Override
protected connection.Result&lt;InetAddress&gt; doInBackground(String... hostnumber) {
connection.Result&lt;InetAddress&gt; result;
try {
result = new connection.Result.Success(InetAddress.getByName(String.valueOf(hostnumber)));
} catch (UnknownHostException e) {
e.printStackTrace();
result = new connection.Result.Failure(e);
}catch (Exception e) {
result = new connection.Result.Failure(e);
}
return result;
}
@Override
protected void onPostExecute(connection.Result&lt;InetAddress&gt; result) {
if (result instanceof connection.Result.Success) {
output.setText((CharSequence) ((connection.Result.Success&lt;InetAddress&gt;) result).data);
} else if (result instanceof connection.Result.Failure) {
Throwable error = ((connection.Result.Failure&lt;InetAddress&gt;) result).error;
Toast.makeText(Lookup.this,&quot;Please Check The Address!: &quot; +error, Toast.LENGTH_SHORT).show();
}
}
};
task.execute(hostnumber.toString());
};
})
;}
}
class connection extends Activity {
static class Result&lt;T&gt; {
static class Success&lt;T&gt; extends Result&lt;T&gt; {
public T data;
public Success(T data) {
this.data = data;
}
}
static class Failure&lt;T&gt; extends Result&lt;T&gt; {
public Throwable error;
public Failure(Throwable error) {
this.error = error;
}
}
}
}

But I'm still facing the problem with this class

This is the XML FILE:

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
xmlns:tools=&quot;http://schemas.android.com/tools&quot;
android:layout_width=&quot;match_parent&quot;
android:layout_height=&quot;match_parent&quot;
tools:context=&quot;.Lookup&quot;&gt;
&lt;EditText
android:id=&quot;@+id/hostnumber&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_marginTop=&quot;98dp&quot;
android:ems=&quot;10&quot;
android:inputType=&quot;textUri|textPersonName&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toTopOf=&quot;parent&quot; /&gt;
&lt;Button
android:id=&quot;@+id/submit&quot;
android:layout_width=&quot;wrap_content&quot;
android:layout_height=&quot;wrap_content&quot;
android:layout_marginEnd=&quot;61dp&quot;
android:text=&quot;Button&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintTop_toBottomOf=&quot;@+id/hostnumber&quot; /&gt;
&lt;TextView
android:id=&quot;@+id/output&quot;
android:layout_width=&quot;100dp&quot;
android:layout_height=&quot;47dp&quot;
android:layout_marginStart=&quot;63dp&quot;
android:layout_marginTop=&quot;8dp&quot;
android:layout_marginEnd=&quot;312dp&quot;
android:text=&quot;TextView&quot;
app:layout_constraintEnd_toEndOf=&quot;parent&quot;
app:layout_constraintHorizontal_bias=&quot;0.186&quot;
app:layout_constraintStart_toStartOf=&quot;parent&quot;
app:layout_constraintTop_toBottomOf=&quot;@+id/submit&quot; /&gt;
&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

I've tried a lot of solutions with Fixing the internet part but still no clue. If you can have any idea with this or where i'm wrong .. thanks!!1

huangapple
  • 本文由 发表于 2020年8月11日 05:09:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/63348062.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定