[英]How to update TextView using AsyncTask
Background Story:背景故事:
This app listens to my gmail account for latest mail and retrieves it.这个应用程序监听我的 gmail 帐户以获取最新邮件并检索它。 It then displays the content of the mail on the app.
然后它会在应用程序上显示邮件的内容。
Problem:问题:
I'm new to Android Programming.我是 Android 编程新手。 Now before I get bashed for not doing my research, let me tell you guys that I did.
现在,在我因为没有做研究而受到抨击之前,让我告诉你们我做了。 I know I am not allowed to update TextView in doInBackground() method.
我知道我不允许在 doInBackground() 方法中更新 TextView。 And I know that I have to do it onPostExecute instead.
而且我知道我必须改为 onPostExecute 。 My question is how do I do that?
我的问题是我该怎么做? How do I make use of onPostExecute to update my label in the context of my application.
如何在我的应用程序上下文中使用 onPostExecute 更新我的 label。 Thank you so much!
太感谢了!
EDIT:编辑:
All I want is to display the latest content of my mail onto the TextView.我只想在 TextView 上显示我邮件的最新内容。
public class MainActivity extends AppCompatActivity {
//Alarm Sound Global Declaration
private TextView lblDegrees;
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Permit all, Remove strict mode
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
//Declaration of Widgets
lblDegrees = (TextView) findViewById(R.id.lblDegrees);
new receiveMail().execute();
}
public class receiveMail extends AsyncTask {
protected Object doInBackground(Object[] objects) {
Store store = null;
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imaps");
try {
Session session = Session.getInstance(props, null);
store = session.getStore();
store.connect("imap.gmail.com", 993, "*****@gmail.com", "****"); //Commented this on purpose
final Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
int msgCount;
do {//go through all the unread emails in the inbox at least once
msgCount = inbox.getMessageCount();//set how many messages are in the inbox when the array is created
// Fetch unseen messages from inbox folder
Message[] messages = inbox.search(
new FlagTerm(new Flags(Flags.Flag.SEEN), false));
for (javax.mail.Message msg : messages) {
//process emails hereSystem.out.println("---------------------------------------------------");
System.out.println("Unread Messages : " + inbox.getUnreadMessageCount());
System.out.println("Send Date : " + msg.getSentDate());
System.out.println("Subject : " + msg.getSubject());
System.out.println("Content : " + msg.getContent().toString());
//Substring the celsius here later
}
//if a new message came in while reading the messages start the loop over and get all unread messages
} while (inbox.getMessageCount() != msgCount);
//add listener
inbox.addMessageCountListener(new MessageCountAdapter() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void messagesAdded(MessageCountEvent ev) {
//Show notification here
show_Notification();
alarm_On();
Message[] messages = ev.getMessages();
for (Message msg : messages) {
//process emails here
try {
System.out.println("Unread Messages : " + inbox.getUnreadMessageCount());
} catch (MessagingException e) {
e.printStackTrace();
}
try {
System.out.println("Send Date : " + msg.getSentDate());
} catch (MessagingException e) {
e.printStackTrace();
}
try {
System.out.println("Subject : " + msg.getSubject());
} catch (MessagingException e) {
e.printStackTrace();
}
try {
System.out.println("Content : " + msg.getContent().toString());
} catch (IOException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
});
// wait for new messages
while (inbox.isOpen()) {
//every 25 minutes poke the server with a inbox.getMessageCount() to keep the connection active/open
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
final Runnable pokeInbox = new Runnable() {
@Override
public void run() {
try {
System.out.println(inbox.getMessageCount());
} catch (MessagingException ex) {
//nothing doin'
}
}
};
scheduler.schedule(pokeInbox, 20, TimeUnit.MINUTES);
((IMAPFolder) inbox).idle();
}
} catch (FolderClosedException e) {
e.printStackTrace();
System.out.println("error connection was dropped");
if (store != null) {
try {
store.close();
} catch (MessagingException ex) {
ex.printStackTrace();
}
}
// loadUnreadEmails();//restarts listening for email if the connection times out
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} finally {
if (store != null) {
try {
store.close();
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
return store;
}
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
lblDegrees.setText(result);
}
protected void onPreExecute() {
}
protected void onProgressUpdate(String text) {
}
}
Don't run on the UI thread, because this defeats the whole idea of asynchronous execution (and this might only work while it's an inner class)... this creates a dependency where there should be none.不要在 UI 线程上运行,因为这违背了异步执行的整个想法(这可能只在它是一个内部类时才有效)......这会创建一个不应该存在的依赖项。
But write an interface
eg.但是写一个
interface
,例如。 with a method onCompleted()
, and let the Activity
implement it - then the Activity
which implements that interface
can be passed as listener into the constructor of AsyncTask
- and be triggered .onPostExecute()
.使用方法
onCompleted()
,并让Activity
实现它 - 然后实现该interface
的Activity
可以作为侦听器传递到AsyncTask
的构造函数中 - 并被触发.onPostExecute()
。 The same interface can also be used for non-standard progress updates and alike, when adding further callback methods.当添加更多回调方法时,相同的接口也可用于非标准进度更新等。
This would be one simple interface
:这将是一个简单的
interface
:
public interface SomeListener {
void onCompleted(String result);
}
This would be the declaration of the class:这将是 class 的声明:
public class MainActivity extends AppCompatActivity implements SomeListener ...
And the constructor of the AsyncTask
:以及
AsyncTask
的构造函数:
private SomeListener listener = null;
public void receiveMail(SomeListener listener) {
this.listener = listener;
}
To be triggered onPostExecute
with:通过以下方式触发
onPostExecute
:
if(this.listener != null) {
this.listener.onCompleted("some result");
}
And in the callback, one can then update the TextView
:然后在回调中,可以更新
TextView
:
@override
public void onCompleted(String result) {
this.lblDegrees.setText(result);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.