יום חמישי, אוקטובר 28

Explicit Intent - העברת הודעות בין Activities

עקרונות הפעולה של ה-Intents תוארו בפרק המבוא להעברת הודעות, כך שנוכל לעבור מיד להדגמה. באפליקציה שהכנתי מוגדרים שני Activities. הודעה נשלחת מ-Activity האחד לשני. השני מחזיר תשובה לראשון. כל אחד מהם מלווה פעולתו בהדפסות למסך. פעולת שליחת ההודעה מתחילה עם לחיצה על כפתור Send Message.
מצא קישור לקבצי המקור בתחתית הדף.
נראה 3 תצוגות המתקבלות בהרצת האפליקציה:
תצוגת המערכת לפני ההפעלה - פאזה 1:



תצוגת המערכת בסוף התהליך- פאזה 3:


תצוגת המערכת במצב הביניים, מיד עם קליטת התגובה ע" ה  -Receive Activity- פאזה 3:
היות שה-Receive Activity נמצא בפעולה למשך זמן קצר בלבד, לא ניתן להבחין בהודעה שהוא שולח למסך.נפצה על כך עם הודעת pop-up שאמנם תשלח על ידי ה- Receive Activity  אבל נוכל להבחין בה.  אחרי הקדמה זו, הנה תמונת המסך מיד אחרי קבלת ההודעה ע"י ה-Receive Activity:



נעבור לסקירת קוד עצמו. האפליקציה בנויה משני classes  לכן דרושים שני קבצי מקור של Java: אחד עבור ה- Activity ששולח את ההודעה והקובץ השני עבור מקבל ההודעה. לא נתעכב על קבצי ה-Layout וה- Manifest. אין בהם אלמנטים שלא נדונו בפרקים קודמים.
נתחיל עם הקוד של שולח ההודעה, הנמצא בבקובץ MessageCalling.java. לשם נוחות הקוד מובא כולו כאן, אך בהמשך נדון בחלקים המעניינים הדורשים הסבר.

package com.ahs.ronenh.expintent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

  1. public class MessageCalling extends Activity {
  2.     public final static int RECEIVE_MESSAGE = 0;
  3.     /** Called when the activity is first created. */
  4.     @Override
  5.     public void onCreate(Bundle savedInstanceState) {
  6.         super.onCreate(savedInstanceState);
  7.         setContentView(R.layout.main);
  8.         Button sendMessage = (Button) findViewById(R.id.send);
  9.         Button CleanScreen = (Button) findViewById(R.id.clean);
  10.         sendMessage.setOnClickListener(new View.OnClickListener() {
  11.             public void onClick(View view) {
  12.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  13.                 msg2screen.setText("");
  14.                 Intent pingIntent = new Intent();
  15.                 pingIntent.setClass(MessageCalling.this, MessageReceiving.class);
  16.                 pingIntent.putExtra( "extra1", new String( "Message Received: Can you hear us?" ) );
  17.                 startActivityForResult(pingIntent, RECEIVE_MESSAGE);
  18.              }
  19.         });
  20.         CleanScreen.setOnClickListener(new View.OnClickListener() {
  21.             public void onClick(View view) {
  22.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  23.                  msg2screen.setText("");
  24.              }
  25.         });
  26.     }
  27.     protected void onActivityResult(int requestCode, int resultCode, Intent data){
  28.         switch(requestCode) {
  29.             case RECEIVE_MESSAGE:
  30.                 String     rec1    = data.getStringExtra("extra1");     
  31.                 Integer rec2    = data.getIntExtra("extra2",0);     
  32.      
  33.             if( rec1 != null ) {
  34.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  35.                 msg2screen.setText( rec1 + " " + rec2);
  36.             }
  37.          }
  38.     }
  39. }


ב- MessageCalling שתי מתודות עיקריות: ()onCreate, אודותיה כבר דנו, והיא המתודה המופעלת עם יצירת האובייקט. 
המתודה השניה ()onActivityResult היא callback שמופעל כאשר התשובה להודעה מגיעה.
שורה 6- כרגיל, כריעה ל-onCreate של class ה"אבא".
שורה 7 - בניית ה- UI על פי ה- layout.
שורה 8-9: הגדרת האובייקטים לכפתורי המסך: שליחת הודעה וניקוי תצוגה.
שורה 10-19: רגיסטרציה של callback עבור כפתור שליחת ההודעה.
שורה 11: המתודה onClick, היא ה-callback שיופעל עם הלחיצה על כפתור send.
שורה 12: השמת אוביקט מסוג TextView, המשמש לתצוגת טקסט ב- UI.
שורה 13: ניקוי התצוגה.

שורות 14-18: הכנת ה- Intent ושליחתו.
שורה 14: יצירת אוביקט מסוג Intent.
שורה 15: היות שמדובר ב explicit intent יש לציין במפורש את יעד ההודעה. זה נעשה ע"י המתודה של  ה-Intent הבא: setClass(context, class, כאשר היעד של ההודעה הוא MessageReceiving.class.
שורה 16: הוספת שדה ה-extra ב-intent. כאן מוכנס string שיודפס ע"י האובייקט המקבל.
שורה 17: שליחת ה-Intent ע"י המתודה  (startActivityForResult(intent, id. מתודה זו תפעיל את ה- Activity המקבל. ה- Activity השולח מצפה לתשובה אסינכרונית - זו התוצאה הנשלחת חזרה. עם קבלת התשובה, יופעל ה-callback אותו נסקור מיד.
שורות 20 עד 25 הם ה- callback של כפתור ניקוי המסך.
שורה 27: ה- callback שמופעל עם קבלת התשובה להודעה/
שורה 29: בדיקת הסוג של ההודעה- זה הזהוי שהוצמד להודעה המקורית.
שורות 30-31: שליפת שדות ה-extra מה- Intent. שדה אחד מסוג string והשני integer.
שורה 34: יצירת אוביקט מסוג TextVeiw. השדה שהוגדר לו ב- UI הוגדר בקובץ ה-Layout כ-pong_message לעומת ping_message שהוגדר עבור ההודעה היוצאת.
שורה 35: הדפסת שדות ה-extra על המסך. ראה התמונה של "פאזה 3".


כעת ניסקור את קובץ השני, MessageReceiving.java:



package com.ahs.ronenh.expintent;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

/**
 * @author ronen
 *
 */
  1. public class MessageReceiving extends Activity{
  2.     /** Called with the activity is first created. */
  3.     @Override
  4.     public void onCreate(Bundle savedInstanceState)
  5.     {
  6.         super.onCreate(savedInstanceState);
  7.         setContentView(R.layout.main);
  8.         String extraMsg1 = getIntent().getExtras().getString("extra1");
  9.         if( ( extraMsg1 != null ) ) {
  10.           TextView msg2screen = (TextView)findViewById(R.id.ping_message);
  11.           msg2screen.setText(extraMsg1);
  12.          Toast.makeText(this, "Received Message:" + extraMsg1, Toast.LENGTH_LONG).show();
  13.         }
  14.         else
  15.         {
  16.              Log.e("Received Extra is null", "null");
  17.         }
  18.         Intent pongIntent = new Intent();
  19.         pongIntent.putExtra("extra1", "Response received: Yes, we can hear yall!");
  20.         pongIntent.putExtra("extra2", new Integer(555) );
  21.         setResult(RESULT_OK,pongIntent);
  22.         finish();
  23.     }
  24. }
 ה- MessageReceiving class מקבל את ה- Intent ושולח תשובה. הוא מכיל את המתודה ()onCreate בלבד.

שורה 8: שולפת את שדה ה-extra מה- intent הנקלט.
שורה 10: יצירת אובייקט מסוג TextView, המשוייך לאלמנט ה-ping_message ב-Layout של ה- UI.
שורה 11: שליחת שדה ה-extra שהתקבל ל-UI. הערה: לא נוכל לספיק לראות תצוגה זו, היות שה-Activity הנ"ל יתחלף במהירות חזרה ל-Activity השולח, עם שליחת התשובה. כזכור, עם כניסת Activity חדש, התצוגה של הקודם נעלמת.

שורה 12: "פיצוי" על העלמות ההודעה ב- UI, כפי שהוסבר בהערה הנ"ל: במקום זה, נדפיס הודעה בעזרת האובייקט Toast שמייצר הודעות pop-up.
שורה 18-21: בניית התשובה ושליחתה.
שורה 18: יצירת אובייקט intent.

שורות 19-20: הכנסת ערכים לשדה ה-extra. הם יודפסו למסך על-ידי ה- ()onActivityResult כפי שתואר קודם.
שורה 21:()setResult שולחת את התשובה ומפעילה את האובייקט MessageCalling.

למדנו די הרבה היום...:-).
קישור לקבצי המקור.

4 תגובות:

  1. הקישור לקבצי המקור לא פעיל

    השבמחק
  2. הקישור אמור להיות תקין עכשיו.

    השבמחק
  3. בהסבר שורה 6. קריאה ולא קריעה

    השבמחק