英文:
Singleton with Android
问题
I'm having a bit of trouble using the singleton pattern correctly in my android studio project. I created a textView in my mainActivity class in which I want to set the text of that textView the string value of the variable "a" in the GrouseSingleton class. However, the textView always displays as "hello" (the way it was initialized) and not the actual string it should be (it should be "mainly cloudy skies", parsed from the website). I'm assuming that I'm not set the variable "a" correctly in the singleton class. Any help would be appreciated, thanks!
SINGLETON CLASS CODE:
public class GrouseSingleton extends AppCompatActivity {
private static GrouseSingleton instance = null;
public Document grouseWeather;
public String a = "hello";
private GrouseSingleton() throws IOException {
startThread();
}
public static GrouseSingleton getInstance() throws IOException {
if (instance == null) {
instance = new GrouseSingleton();
}
return instance;
}
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread(new Runnable() {
public void run() {
a = grouseWeather.select("h3.metric").first().text();
setA(a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void setA(String a) {
this.a = a;
}
}
MAIN ACTIVITY CODE:
try {
grouseSingleton = GrouseSingleton.getInstance();
} catch (IOException e) {
e.printStackTrace();
}
TextView tv45 = findViewById(R.id.textView45);
tv45.setText(grouseSingleton.a);
(Note: I've removed the HTML escape codes for double quotes to make the code more readable.)
英文:
I'm having a bit of trouble using the singleton pattern correctly in my android studio project. I created a textView in my mainActivity class in which I want to set the text of that textView the string value of the variable "a" in the GrouseSingleton class. However, the textView always displays as "hello" (the way it was initialized) and not the actual string it should be (it should be "mainly cloudy skies", parsed from the website). I'm assuming that I'm not set the variable "a" correctly in the singleton class. Any help would be appreciated, thanks!
SINGLETON CLASS CODE:
public class GrouseSingleton extends AppCompatActivity {
private static GrouseSingleton instance = null;
public Document grouseWeather;
public String a = "hello";
private GrouseSingleton() throws IOException {
startThread();
}
public static GrouseSingleton getInstance() throws IOException {
if (instance == null) {
instance = new GrouseSingleton();
}
return instance;
}
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread( new Runnable()
{
public void run()
{
a = grouseWeather.select("h3.metric").first().text();
setA(a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
public void setA(String a) {
this.a = a;
}
}
MAIN ACITVITY CODE:
try {
grouseSingleton = GrouseSingleton.getInstance();
} catch (IOException e) {
e.printStackTrace();
}
TextView tv45 = findViewById(R.id.textView45);
tv45.setText(grouseSingleton.a);
答案1
得分: 1
Your singleton is fine. The issue is that you create the instance of class GrouseSingleton
and then right after that you get the value of a
which is the default value "hello". So you need to use an interface
like below to inform your activity
when the value of a
is fetched from the server:
public interface ResultListener {
void onResultFetched(int textViewId, String txt);
}
In your Activity:
try {
grouseSingleton = GrouseSingleton.getInstance(new ResultListener () {
@Override
public void onResultFetched(int textViewId, String txt) {
TextView tv45 = findViewById(id);
tv45.setText(txt);
}
});
grouseSingleton.startThread();
} catch (IOException e) {
e.printStackTrace();
}
Set the listener in your GrouseSingleton
class:
private static ResultListener listener;
public static GrouseSingleton getInstance(ResultListener listener) throws IOException {
if (instance == null) {
instance = new GrouseSingleton();
GrouseSingleton.listener = listener;
}
return instance;
}
And in your startThread
method:
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread( new Runnable()
{
public void run()
{
a = grouseWeather.select("h3.metric").first().text();
listener.onResultFetched(txtViewId, a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
英文:
Your singleton is fine. The issue is that you create the instance of class GrouseSingleton
and then right after that you get the value of a
which is the default value "hello" . So you need to use an interface
like below to inform your activity
when the value of a
is fetched from server:
public interface ResultListener {
void onResultFetched(int textViewId, String txt);
}
In your Activity:
try {
grouseSingleton = GrouseSingleton.getInstance(new ResultListener () {
@Override
public void onResultFetched(int textViewId, String txt) {
TextView tv45 = findViewById(id);
tv45.setText(txt);
});
grouseSingleton.startThread();
} catch (IOException e) {
e.printStackTrace();
}
set the listener in your GrouseSingleton
class:
private static ResultListener listener;
public static GrouseSingleton getInstance(ResultListener listener) throws IOException {
if (instance == null) {
instance = new GrouseSingleton();
GrouseSingleton.listener = listener;
}
return instance;
}
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread( new Runnable()
{
public void run()
{
a = grouseWeather.select("h3.metric").first().text();
listener.onResultFetched(txtViewId, a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
答案2
得分: 0
所有代码都没问题。但问题在于,在加载数据之前,textview
设置默认值为 hello
。加载数据后,它无法更新该值。为了简单实现这一点,只需在调用单例时将您的 textView
作为参数传递,如下所示:
SingletonClass:
public class GrouseSingleton extends AppCompatActivity {
private static GrouseSingleton instance = null;
public Document grouseWeather;
public String a = "hello";
TextView textView;
private GrouseSingleton(TextView textView) throws IOException {
this.textView = textView;
startThread();
}
public static GrouseSingleton getInstance(TextView textView) throws IOException {
if (instance == null) {
instance = new GrouseSingleton(textView);
}
return instance;
}
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread(new Runnable() {
public void run() {
a = grouseWeather.select("h3.metric").first().text();
textView.setText(a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
然后在 MainActivity 中使用:
TextView tv45 = findViewById(R.id.textView45);
try {
grouseSingleton = GrouseSingleton.getInstance(tv45);
} catch (IOException e) {
e.printStackTrace();
}
tv45.setText(grouseSingleton.a);
注意:上述代码片段中的 HTML 实体编码 "
已经被替换为双引号 "
,以便正确呈现代码。
英文:
All code is fine. But the problem is before load data textview
set default value hello
. Afterload data it's cannot update the value. To simply achieve this just sent your textView
as a parameter when calling your singleton. like:
SingletonClass:
public class GrouseSingleton extends AppCompatActivity {
private static GrouseSingleton instance = null;
public Document grouseWeather;
public String a = "hello";
TextView textView;
private GrouseSingleton(TextView textView) throws IOException {
this.textView = textView;
startThread();
}
public static GrouseSingleton getInstance(TextView textView) throws IOException {
if (instance == null) {
instance = new GrouseSingleton(textView);
}
return instance;
}
public void startThread() throws IOException {
new Thread() {
public void run() {
try {
grouseWeather = Jsoup.connect("https://www.grousemountain.com/current_conditions#weather").get();
runOnUiThread( new Runnable()
{
public void run()
{
a = grouseWeather.select("h3.metric").first().text();
textView.setText(a);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
}
And from MAinActivity:
TextView tv45 = findViewById(R.id.textView45);
try {
grouseSingleton = GrouseSingleton.getInstance(tv45);
} catch (IOException e) {
e.printStackTrace();
}
tv45.setText(grouseSingleton.a);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论