1. Download our Official Android App: Forums for Android!

UDP message handling - spaghetti code. Is there a better way?

Discussion in 'Android Development' started by Gregary Boyles, Oct 12, 2017.

  1. Gregary Boyles

    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    30
    Joined:
    Oct 1, 2017

    Oct 1, 2017
    30
    0
    15
    Inheritance hierarchy
    AppCompatibleActivity -> CBaseActivity -> CWifiActivity -> CUDPActivity -> CSearchAutoSolActivity
    AsyncTask ->CSearchTask
    Thread -> CUDPThread
    Handler -> CUDPHandler

    Basically I am trying to create re-usable code with this hierarchy so that I don't have to 're-ivent the wheel' every time I want to write an app that sends and receives UDP messages!

    If this sample app (http://android-er.blogspot.com.au/2016/06/android-datagramudp-server-example.html) is accurate then basically I am forced into this arrangement:

    1) CSearchAutoSolActivity object - click search button
    2) Create CSearchTask object - iterate through remote irrigation stations 1-12 and update UI controls as search proceeds
    3) Create CUDPThread object and load it with the message to be sent over UDP, the destination IP address and the port number.
    4) Create a CUDPHandler object as a message buffer between the CUDPThreadand the CSearchAutoSolActivity.
    .
    .
    .
    1) CSearchTask object creates the message to be sent over UDP and gives it to CUDPThread
    2) CUDPThread sends the UDP message and waits for a response.
    3) CUDPThread sends a message to CUDPHandler detailing if a response was received or not.
    4) CUDPHandler pass the message on to CSearchAutoSolActivity through some virtual functions I setup in it and its base class.
    5) The virtual functions in CSearchAutoSolActivity passes the UDP response (or no response) on to CSearchTask so that it can update the UI controls in CSearchAutoSolActivity

    In Microsoft Visual Studio I can accomplish all this in a single custom function in my CDialog derived class!

    Unless there is a simpler way to do all this that escapes me, this all seems like spaghetti code to me and I certainly don't want to have to re-create it afresh with every new app I write that uses UDP messaging.

    Is there a simpler way to do all this in Android Studio????

    And I am still no closer to successfully sending a UDP message under Android studio because my app is reporting that the local IP address is 127.0.0.1.
    And I am told this means I am not connected to the network!

    WHY is it so difficult and complicated to send a UDP message with Android Studio?

    It took me about a day to figure it out and get it working with Microsoft Visual Studio!

    But Android Studio is proving to be a damn nightmare!



    class CSearchAutoSolActivity and class CSearchTask
    Code (Text):
    1.  
    2. package com.example.greg.irrigationcontroller;
    3.  
    4. import android.content.Intent;
    5. import android.os.AsyncTask;
    6. import android.os.Bundle;
    7. import android.util.Log;
    8. import android.view.View;
    9. import android.widget.Button;
    10. import android.widget.ProgressBar;
    11. import android.widget.TextView;
    12. import java.io.IOException;
    13. import java.net.DatagramPacket;
    14. import java.net.DatagramSocket;
    15. import java.net.InetAddress;
    16.  
    17. /**
    18. * Created by Greg on 5/10/2017.
    19. */
    20.  
    21. public class CSearchAutoSolActivity extends CUDPActivity implements View.OnClickListener
    22. {
    23.     @Override
    24.     protected void onCreate(Bundle savedInstanceState)
    25.     {
    26.         super.onCreate(savedInstanceState);
    27.         setContentView(R.layout.activity_search_auto_sol);
    28.  
    29.         if (m_app != null)
    30.             m_app.SetCurrentActivity(CSearchAutoSolActivity.this);
    31.         m_textviewResults = (TextView)findViewById(R.id.id_textview_results);
    32.         m_textviewTrying = (TextView)findViewById(R.id.id_textview_trying);
    33.         m_progress = (ProgressBar)findViewById(R.id.id_progressbar_search);
    34.         m_buttonStart = (Button)findViewById(R.id.id_button_start);
    35.         m_buttonStart.setOnClickListener(CSearchAutoSolActivity.this);
    36.         m_buttonBack = (Button)findViewById(R.id.id_button_back);
    37.         m_buttonBack.setOnClickListener(CSearchAutoSolActivity.this);
    38.  
    39.         m_handlerUDPClient = new CUDPHandler(this);
    40.     }
    41.  
    42.     @Override
    43.     public void onClick(View view)
    44.     {
    45.         Intent intent = null;
    46.  
    47.         switch (view.getId())
    48.         {
    49.             case R.id.id_button_start:
    50.                 m_buttonStart.setEnabled(false);
    51.                 m_searchtask = new CSearchTask(this);
    52.                 m_searchtask.execute();
    53.                 break;
    54.             case R.id.id_button_back:
    55.                 intent = new Intent(getApplicationContext(), CMainActivity.class);
    56.                 break;
    57.         }
    58.         if (intent != null)
    59.         {
    60.             finish();
    61.             startActivity(intent);
    62.         }
    63.     }
    64.  
    65.     @Override
    66.     public void updateState(final String strMsg)
    67.     {
    68.         Log.d("CSearchAutoSolActivity", strMsg);
    69.     }
    70.  
    71.     @Override
    72.     public void updateMessageSent(final String strMsg)
    73.     {
    74.         Log.d("CSearchAutoSolActivity", strMsg);
    75.     }
    76.  
    77.     @Override
    78.     public void updateMessageReceived(final String strMsg)
    79.     {
    80.         if (strMsg.contains("notify"))
    81.         {
    82.             String strIPAddr = new String(), strField = new String();
    83.             int nStation = 0;
    84.  
    85.             deleteField(strMsg, "notify");
    86.             strField = getNextField(strMsg);
    87.             nStation = Integer.parseInt(strField);
    88.             deleteField(strMsg, strField);
    89.             strIPAddr = getNextField(strMsg);
    90.  
    91.             m_searchtask.updateStationResponse(nStation, strIPAddr);
    92.             m_app.SetStationActive(nStation, true);
    93.             m_app.SetStationIPAddress(nStation, strIPAddr);
    94.         }
    95.     }
    96.  
    97.     @Override
    98.     public void updateNoResponse(final String strMsg)
    99.     {
    100.         if (strMsg.contains("request"))
    101.         {
    102.             String strField = new String();
    103.             int nStation = 0;
    104.  
    105.             deleteField(strMsg, "request");
    106.             strField = getNextField(strMsg);
    107.             nStation = Integer.parseInt(strField);
    108.  
    109.             m_searchtask.updateStationNoResponse(nStation);
    110.             m_app.SetStationActive(nStation, false);
    111.         }
    112.     }
    113.  
    114.     @Override
    115.     public void updateEnd(final String strMsg)
    116.     {
    117.         m_buttonStart.setEnabled(true);
    118.     }
    119.  
    120.     @Override
    121.     public void updateException(final String strMsg)
    122.     {
    123.         m_strDebug = strMsg;
    124.     }
    125.  
    126.     protected TextView m_textviewResults, m_textviewTrying;
    127.     protected Button m_buttonStart, m_buttonBack;
    128.     protected ProgressBar m_progress;
    129.     protected CSearchTask m_searchtask;
    130.  
    131.  
    132.     protected class CSearchTask extends AsyncTask<Void/**param type*/, Void/**progress type*/, String/**result type*/>
    133.     {
    134.         public CSearchTask(final CUDPActivity actParent)
    135.         {
    136.             m_actParent = actParent;
    137.             m_strResults = new String();
    138.             m_strTrying = new String();
    139.             m_nProgress = 0;
    140.         }
    141.  
    142.         public void updateStationResponse(final int nStation, final String strIPAddr)
    143.         {
    144.             m_strResults += "Station " + String.valueOf(nStation) + ": response received from " + strIPAddr + "!";
    145.         }
    146.  
    147.         public void updateStationNoResponse(final int nStation)
    148.         {
    149.             m_strResults += "Station " + String.valueOf(nStation) + ": no response!";
    150.         }
    151.  
    152.         @Override
    153.         protected String doInBackground(Void...Void)
    154.         {
    155.             String strResult = new String("");
    156.  
    157.             searchForStations();
    158.  
    159.             return strResult;
    160.         }
    161.  
    162.         @Override
    163.         protected void onProgressUpdate(Void...param)
    164.         {
    165.             m_textviewResults.setText(m_strResults);
    166.             m_textviewTrying.setText(m_strTrying);
    167.             m_progress.setProgress(m_nProgress);
    168.         }
    169.  
    170.         @Override
    171.         protected void onPostExecute(String strResult)
    172.         {
    173.             m_buttonStart.setEnabled(true);
    174.             m_textviewTrying.setText("Finished");
    175.         }
    176.  
    177.         @Override
    178.         protected void onPreExecute()
    179.         {
    180.         }
    181.  
    182.         protected void searchForStations()
    183.         {
    184.             if ((m_app != null) && (m_wifiManag != null) && m_wifiManag.isWifiEnabled() && (m_textviewResults != null) && (m_textviewTrying != null))
    185.             {
    186.                 CIPAddress ipAddrLocal = new CIPAddress();
    187.                 ipAddrLocal.setLocalIPAddr();
    188.  
    189.                 String strRequest = new String("request") + m_strUDPDelim, strMsg = new String();
    190.                 int nProgressInc = 100 / m_app.m_nMaxStations + 1;
    191.  
    192.                 for (int nStation = 1; nStation <= m_app.m_nMaxStations; nStation++)
    193.                 {
    194.                     m_strTrying = new String("Trying station ") + String.valueOf(nStation) + new String("...");
    195.                     publishProgress();
    196.                     strMsg = strRequest + String.valueOf(nStation) + m_strUDPDelim + ipAddrLocal.toString() + m_strUDPDelim;
    197.                     sendMessage(m_actParent, strMsg, ipAddrLocal.toBroadcast(), m_nUDPPort, true);
    198.                     m_nProgress += nProgressInc;
    199.                 }
    200.                 publishProgress();
    201.             }
    202.         }
    203.  
    204.         protected String m_strResults, m_strTrying;
    205.         protected int m_nProgress;
    206.         protected CUDPActivity m_actParent = null;
    207.     }
    208. }
    209.  
    class CUDPActivity
    Code (Text):
    1.  
    2. package com.example.greg.irrigationcontroller;
    3.  
    4. import android.os.Bundle;
    5.  
    6.  
    7.  
    8. /**
    9. * Created by Greg on 8/10/2017.
    10. */
    11.  
    12. public class CUDPActivity extends CWifiActivity
    13. {
    14.     @Override
    15.     protected void onCreate(Bundle savedInstanceState)
    16.     {
    17.         super.onCreate(savedInstanceState);
    18.     }
    19. .
    20. .
    21. .
    22. .
    23. .
    24. .
    25. }
    26.  
    class CUDPActivity
    Code (Text):
    1.  
    2. package com.example.greg.irrigationcontroller;
    3.  
    4. import android.os.Bundle;
    5.  
    6.  
    7.  
    8. /**
    9. * Created by Greg on 8/10/2017.
    10. */
    11.  
    12. public class CUDPActivity extends CWifiActivity
    13. {
    14.     @Override
    15.     protected void onCreate(Bundle savedInstanceState)
    16.     {
    17.         super.onCreate(savedInstanceState);
    18.     }
    19.  
    20.     String getNextField(final String strMsg)
    21.     {
    22.         int nPos = strMsg.indexOf(m_strUDPDelim);
    23.         String strField = strMsg.substring(0, nPos);
    24.         return strField;
    25.     }
    26.  
    27.     String deleteField(String strMsg, final String strField)
    28.     {
    29.         int nPos = strMsg.indexOf(m_strUDPDelim);
    30.         strMsg = strMsg.substring(nPos);
    31.         return strMsg;
    32.     }
    33.  
    34.     public void updateState(final String strMsg)
    35.     {
    36.     }
    37.  
    38.     public void updateMessageSent(final String strMsg)
    39.     {
    40.     }
    41.  
    42.     public void updateMessageReceived(final String strMsg)
    43.     {
    44.     }
    45.  
    46.     public void updateNoResponse(final String strMsg)
    47.     {
    48.     }
    49.  
    50.     public void updateEnd(final String strMsg)
    51.     {
    52.     }
    53.  
    54.     public void updateException(final String strMsg)
    55.     {
    56.     }
    57.  
    58.     protected void sendMessage(final CUDPActivity actUDP, final String strMessage, final String strIPAddr, final int nPort, final boolean bBroadcast)
    59.     {
    60.         if ((m_app != null) && (m_wifiManag != null) && m_wifiManag.isWifiEnabled())
    61.         {
    62.             //m_handlerUDPClient = new CUDPHandler(actUDP);
    63.             //CUDPThread threadUDPClient = new CUDPThread(strIPAddr, nPort, strMessage, handlerUDPClient);
    64.             //threadUDPClient.start();
    65.         }
    66.     }
    67.     protected final String m_strUDPDelim = "`";
    68.     protected final int m_nUDPPort = 10002;
    69.     protected CUDPHandler m_handlerUDPClient = null;
    70.     protected CUDPThread m_threadUDPClient = null;
    71. }
    72.  
    class CUDPHandler
    Code (Text):
    1.  
    2. package com.example.greg.irrigationcontroller;
    3.  
    4. import android.os.Handler;
    5. import android.os.Message;
    6.  
    7. class CUDPHandler extends Handler
    8. {
    9.    public static final int UPDATE_STATE = 0;
    10.     public static final int UPDATE_MSG_SENT = 1;
    11.     public static final int UPDATE_MSG_REC = 2;
    12.     public static final int UPDATE_NO_RESP = 3;
    13.     public static final int UPDATE_END = 4;
    14.     public static final int UPDATE_EXCEPTION = 5;
    15.  
    16.    private CUDPActivity m_actParent = null;
    17.  
    18.    public CUDPHandler(CUDPActivity actParent)
    19.    {
    20.       super();
    21.         m_actParent = actParent;
    22.    }
    23.  
    24.    @Override
    25.    public void handleMessage(Message msg)
    26.    {
    27.       switch (msg.what)
    28.       {
    29.          case UPDATE_STATE:
    30.             m_actParent.updateState((String)msg.obj);
    31.             break;
    32.             case UPDATE_MSG_SENT:
    33.                 m_actParent.updateMessageSent((String)msg.obj);
    34.                 break;
    35.             case UPDATE_MSG_REC:
    36.                 m_actParent.updateMessageReceived((String)msg.obj);
    37.                 break;
    38.             case UPDATE_NO_RESP:
    39.                 m_actParent.updateNoResponse((String)msg.obj);
    40.                 break;
    41.             case UPDATE_END:
    42.                 m_actParent.updateEnd((String)msg.obj);
    43.                 break;
    44.             case UPDATE_EXCEPTION:
    45.                 m_actParent.updateException((String)msg.obj);
    46.                 break;
    47.          default:
    48.             super.handleMessage(msg);
    49.       }
    50.    }
    51. }
    52.  
     

    Advertisement

    #1 Gregary Boyles, Oct 12, 2017
    Last edited: Oct 12, 2017

Share This Page

Loading...