单例模式在Android中的应用。

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

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);

huangapple
  • 本文由 发表于 2020年8月1日 12:18:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63201725.html
匿名

发表评论

匿名网友

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

确定