【问题标题】:Updating random String every day每天更新随机字符串
【发布时间】:2017-03-31 03:20:53
【问题描述】:

我有不同字符串的 ArrayList。我想每天从这个 ArrayList 中选择一个随机字符串并在 TextView 中显示。我按照此链接中给出的说明进行操作:display a random string in textview once a day for java and android studio 但是出了点问题。 首先,我在 textView 中设置了初始文本。

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mainscreen);
    TextView textview = (TextView) findViewById(R.id.firsttask);
    textview.setText("Z1");

然后我创建 2 个日期: CurrentDate 总是应该显示给定时间。 dateTime 是存储在 SharedPreferences 中的日期。起初,CurrentDate 和 dateTime 是相同的。然后,第二天日期不相等,因此应更新文本并保存 dateTime 以使日期相等。

    Calendar c= Calendar.getInstance();

    SimpleDateFormat df = new SimpleDateFormat("dd-MMM-yyyy");
    String currentDate= df.format(c.getTime());
    String dateTime = df.format(c.getTime());
    saveDate();
    loadDate();
    if(!(dateTime.equals(currentDate))){
        updateList1();
        saveDate();
    }

    public void saveDate (){
    SharedPreferences prefs =     getApplicationContext().getSharedPreferences(MY_PREFS_DATE,         Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = prefs.edit();
    editor.putString("date", dateTime);
    editor.apply();
    }
    public void loadDate (){
    SharedPreferences prefs =        getApplicationContext().getSharedPreferences(MY_PREFS_DATE, Context.MODE_PRIVATE);
    dateTime = prefs.getString("date","default value");
    }

    public void updateList1 (){
    ArrayList<String> task1 = new ArrayList<String>();
    task1.add("t1");
    task1.add("t2");
    task1.add("z3");
    task1.add("z4");
    Random r = new Random();
    task = task1.get(r.nextInt(task1.size()));
    TextView textview = (TextView) findViewById(R.id.firsttask);
    textview.setText(task);
}

此代码不起作用,因为一天后,文本没有更新。它仍然显示“Z1”。我在编程方面很新,我将不胜感激。

【问题讨论】:

    标签: java android date arraylist random


    【解决方案1】:

    它不起作用,因为当您运行此代码时,您首先运行saveDate();,然后运行loadDate();,这将使您的值相等。首先加载然后保存,它应该可以按预期工作;

    【讨论】:

    • 正确。问题中的代码总是保存当前日期,没有先检查保存的日期。
    • 不可否认,这是一个问题。但是,我把 saveDate();和加载日期();以正确的顺序,它仍然没有工作。我认为除了日期之外,我还必须保存当前任务,所以我还添加了 task = prefs.getString("text", "default value");加载日期();和 editor.putString("text", task);保存日期();效果是一样的:当日期更改时,任务会更新,但是当我关闭应用程序并重新打开它时,文本又是“Z1”。我不确定问题出在保存数据、加载数据还是两者兼而有之。
    • 好的,我已正确保存和加载数据,只是忘记将更新后的文本设置为 TextView。您的回答是正确的,谢谢您的帮助。
    【解决方案2】:

    Answer by Dochan 是正确的:您总是保存当前日期,而不是先加载保存的日期进行比较。

    java.time

    此外,您正在使用 Java 最早版本中的麻烦的旧日期时间类。现在是遗留的,被 java.time 类所取代。

    LocalDate

    LocalDate 类表示没有时间和时区的仅日期值。

    时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。

    ZoneId z = ZoneId.of( "America/Montreal" );
    LocalDate today = LocalDate.now( z );
    

    ISO 8601

    将日期时间值序列化为文本时,请使用标准的ISO 8601 格式。这些格式在人类文化中是明智的、直观的,并且是明确的。对于仅日期值,格式为 YYYY-MM-DD,例如 2016-01-23

    java.time 类在解析和生成字符串时默认使用 ISO 8601 格式。

    修改代码

    我会将有关更新的所有逻辑转移到一个方法中,updateMessageIfNewDay。将消息选择逻辑分离为 (a) 可能会发生变化,以及 (b) if-needs-updating 代码不需要知道消息来自哪里,也不需要知道消息是如何选择的。

    您可以检测 JVM 当前的默认时区。但是,共享该 JVM 的任何应用程序的任何线程中的任何代码都可能在任何时刻在运行时更改此设置。因此,如果正确的日期至关重要,请询问用户他们的预期时区。为简单起见,这里我们使用默认区域。

    下面的代码是草稿,从未测试过。

    类上的成员变量:

    LocalDate messageDate ;
    String messageContent ;
    

    我不了解 Android 首选项实用程序,所以我使用伪代码。

    void updateMessageIfNewDay() {
        // Determine the current date.
        ZoneId z = ZoneId.systemDefault() ;  // Or use time zone specified by user: ZoneId.of( "America/Montreal" )
        LocalDate today = LocalDate.now( z ) ;
    
        // Load from storage the date for which we previously displayed a message.
        LocalDate storedMessageDate;
        … if no saved value, leave var null.
            // No code needed here. Leave null.
        … else load string and parse.
            String s = … // load the YYYY-MM-DD string from Android prefs.
            storedMessageDate = LocalDate.parse( s ) ;
        … end if
    
        // Need to update if:
        // (a) no message stored in prefs, or 
        // (b) No message on this object, so not yet displayed (first encounter in this launch of the app), or
        // (c) stored message is old (not equal to today).
        if( ( null == storedMessageDate ) || 
            ( null = this.messageContent ) || 
            ( ! storedMessageDate.isEqual( today ) ) ) 
        {
                // Update values in memory.
                this.messageDate = today ;
                this.messageContent = this.fetchAnotherMessage();
    
                // Update values in storage.
                Prefs.save( "messageDate" , this.messageDate.toString() ) ; // pseudo-code
                Prefs.save( "messageContent" , this.messageContent );
    
                // Update display with contents of this.messageContent.
                … Android UI update code here
         }
    
    }
    

    对于随机选择,您可以使用Math.random() 方便,而不是跟踪您自己的Random 对象。

    private String fetchAnotherMessage() {
        // If called often, save this list as a member on the class, or as a constant. Or if slow-to-load such as database access, save this list.
        // For fast list not called often, don't bother, just instantiate each time.
        int initialCapacity = 4 ;
        List<String> messages = new ArrayList<>( initialCapacity ) ;
        messages.add( "t1" ) ;
        messages.add( "t2" ) ;
        messages.add( "z3" ) ;
        messages.add( "z4" ) ;
    
        // Choose a random from min to max, both inclusive.
        int min = 1 ;
        int max = messages.size() ;
        int range = ( (max - min) + 1 ) ;     
        int n = ( ( (int)(Math.random() * range) ) + min ) ;
        int index = ( n - 1 ) ; // A `List` is accessed by zero-based index number. So subtract one.
        String message = messages.get( index ) ;
        return message ;
    }
    

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。 Hibernate 5 & JPA 2.2 支持 java.time

    从哪里获取 java.time 类?

    【讨论】:

    • 感谢您提供如此广泛的回答。这也很有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    相关资源
    最近更新 更多