2016-06-04 4 views
1

Ich habe eine Methode "send()", die Werte an den Server sendet und dann die Antwort 0 oder 1 vom Server erhält. dann möchte ich eine Methode aktivieren, die prüft, ob es 0 oder 1 ist, und dann möchte ich eine Methode auf MainActivity aktivieren, die von dem Dienst anruft.runOnUiThread vom Dienst zur Aktivität

Dies ist der Service-Code

public class SendThreadCommunication extends Thread { 
private final static String TAG = "SendThreadCommunication"; 
private final int READ_TIMEOUT = 100000; 
private final int CONNECTION_TINEOUT = 100000; 
private Looper myLooper; 
private int mResponseCode; 
private String mData = ""; 

private final ServerRequest req; 
// private RegisterUser user; 
private static String ans; 

public SendThreadCommunication(ServerRequest req) { 

    this.req = req; 
} 

public String readWebData(InputStream stream) { 

    String line = ""; 
    StringBuffer buffer = new StringBuffer(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 

    try { 
     while ((line = reader.readLine()) != null) { 
      buffer.append(line); 
     } 
     reader.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 

    } 
    return buffer.toString(); 

} 

@Override 
public void run() { 
    try { 
     send(); 
     // evaluateDataAndRespondToFragment(mData); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

} 


public void send() throws ClientProtocolException, IOException { 
    OutputStream mOutputStream = null; 
    BufferedWriter mWriter = null; 

    List<NameValuePair> mParameters = req.getParameters(); 

    URL url = null; 
    HttpURLConnection connection = null; 
    try { 
     Looper.prepare(); 
     url = new URL(req.returnRequestUrl()); 
     connection = (HttpURLConnection) url.openConnection(); 
     connection.setReadTimeout(READ_TIMEOUT); 
     connection.setConnectTimeout(CONNECTION_TINEOUT); 
     connection.setRequestMethod(Params.HTTP_REQUEST_METHOD_POST); 
     connection.setDoOutput(true); 
     connection.setDoInput(true); 
     mOutputStream = connection.getOutputStream(); 
     mWriter = new BufferedWriter(new OutputStreamWriter(mOutputStream, Params.UTF8)); 
     String sparams = URLEncodedUtils.format(mParameters, Params.UTF8); 
     mWriter.write(sparams); 
     mWriter.flush(); 

     mResponseCode = connection.getResponseCode(); 
     if (mResponseCode > 203) { 
      mData = readWebData(connection.getErrorStream()); 
      //this.req.getResponse().notGoodServerEroorr(); 
     } else { 
      mData = readWebData(connection.getInputStream()); 

     } 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } finally { 
     if (connection != null) { 
      try { 
       if (mOutputStream != null) 
        mOutputStream.close(); 
       if (mWriter != null) 
        mWriter.close(); 

      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      connection.disconnect(); 
      evaluateDataAndRespondToFragment(mData); 
      myLooper = Looper.myLooper(); 
      Looper.loop(); 
      myLooper.quit(); 

     } 
    } 
    } 

private void evaluateDataAndRespondToFragment(String mData) { 
    Listen lis = this.req.getResponse(); 

    if (mData.equals("1")) 
     lis.good(); 
    else 
     lis.notGood(); 

    if (mData.equals("0")) 
    { 
     lis.userGcmNotRegistered(); 
    } 
    } 
} 

dieser Code Dienst an den Server Werte senden und Antwort. Die Methode "evaluateDataAndRespondToFragment" überprüft ob es 0 oder 1 ist und aktiviert dann die entsprechende Methode. Diese Methode sollte eine andere Methode in der MainActivity auslösen. Ich weiß, dass runOnUiThread dies handhabt, aber ich weiß nicht, wie man es benutzt. Die Methode auf der MainActivity ändern die Benutzeroberfläche.

dies ist der MainActivity Code

public class MainActivity extends Activity implements SensorEventListener, Listen { 

private BroadcastReceiver statusReceiver; 
private IntentFilter mIntent; 
Sensor accelerometer; 
SensorManager sm; 
TextView acceleration; 
SendValues sv; 
int counter3 = 0; 
int counter5 = 0; 
int pastTime = 0; 

private static final String TAG = "MainActivity"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    } 


@Override 
public void good() { 
    Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show(); 
} 

@Override 
public void notGood() { 
    Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show(); 
} 

@Override 
public void userGcmNotRegistered() { 
    Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show(); 
    } 

} 

Hier sollte es aktiv eine der Methoden "gut", "nicht gut" .... ich weiß, dass runOnUiThread es handle aber ich weiß nicht, wie man es benutzt und wo. Wenn mir jemand sagen könnte, was ich tun soll, werde ich mich freuen.

+0

Sie Ihren Code in AsyncTask wickeln können, die Pflege der Threadwechsel stattfindet. – Serg

Antwort

1

Ein Dienst hat keine runOnUiThread Methode, aber Sie Absicht statt verwenden können.

einfach,

  1. eine BroadcastReceiver auf Ihre Aktivität hinzufügen,
  2. hinzufügen Empfänger an Ihren AndroidManifest.xml,
  3. senden Absicht von Ihrem Service.

MainActivity.java

public class MainActivity extends Activity implements SensorEventListener, Listen { 

    private BroadcastReceiver statusReceiver; 
    private IntentFilter mIntent; 
    Sensor accelerometer; 
    SensorManager sm; 
    TextView acceleration; 
    SendValues sv; 
    int counter3 = 0; 
    int counter5 = 0; 
    int pastTime = 0; 

    private static final String TAG = "MainActivity"; 

    statusReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       switch(intent.getIntExtra("status", -1) { 
        case 1: 
         good(); 
         break; 
        case 2: 
         notGood(); 
         break; 
        default: 
         userGcmNotRegistered(); 
       } 
      } 
     }; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     registerReceiver(statusReceiver, new IntentFilter("com.yourpackage.yourapp.GET_STATUS_INTENT"); 
     } 


    @Override 
    public void good() { 
     Toast.makeText(getApplication(), "successful transfer", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void notGood() { 
     Toast.makeText(getApplication(), "UNsuccssful transfer", Toast.LENGTH_LONG).show(); 
    } 

    @Override 
    public void userGcmNotRegistered() { 
     Toast.makeText(getApplication(), "There is some problem, please register again to the App", Toast.LENGTH_LONG).show(); 
     } 

    } 

Eine einfache AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.yourpackage.yourapp" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="19" 
     android:targetSdkVersion="19" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <activity 
      android:name="com.yourpackage.yourapp.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

     <receiver android:name="MainActivity"> 
       <intent-filter> 
         <action android:name="com.yourpackage.yourapp.GET_STATUS_INTENT"> 
         </action> 
       </intent-filter> 
    </receiver> 
    </application> 
</manifest> 

evaluateDataAndRespondToFragment Methode

private void evaluateDataAndRespondToFragment(String mData) { 

    Intent intent = new Intent("com.yourpackage.yourapp.GET_STATUS_INTENT"); 
    intent.putExtra(status, mData); 
    sendBroadcast(intent); 

    } 
} 

Zusätzlich müssen Sie sich in den onResume/onPause-Methoden Ihrer Aktivität registrieren/abmelden.

+0

ich weiß nicht warum, aber in der "sendBroadcast" gibt es mir einen fehler. Es sagt, dass ich eine Methode erstellen muss. Muss ich etwas implementieren? –

+0

Können Sie den ganzen Fehler hinzufügen? – beremaran

+0

"Methode kann nicht aufgelöst werden 'sendBroadcast (android.content.Intent)' –

0

Ein bisschen off Thema; Aber die Antwort von Beremaran ist richtig, Sie können den Hauptthread nicht von einem Dienst erhalten. RunOnUiThread ist jedoch ein sehr wichtiges Konzept, das Sie kennen und verwenden sollten, um zu vermeiden, dass Ihr Haupt-Thread blockiert wird. Wenn Sie Ihren Hauptthread blockieren, wird Ihre App vom System beendet.

Nehmen wir an, Sie haben einige Netzwerkaufgaben zu erledigen, und Sie wissen, dass es einige Zeit dauern kann, das zu tun. Daher startest du einen neuen Thread um die langsame Arbeit zu erledigen.

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     messageFromSlowStuff = doSomeSlowStuff(); 
    }; 
}).start(); 

Nun könnte man die Benutzeroberfläche mit den neuen Daten messageFromSlowStuff auffüllen möchten, aber man kann nicht, weil es nur laut aus dem Haupt-Thread ist.

getActivity().runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     myTextView.setText(messageFromSlowStuff) 
    } 
}); 

Wenn Sie nur eine Ansicht wie in dem Beispiel die Aktualisierung über Sie View.post() eine Alternative zu runOnUiThread verwenden können.

myTextView.post(new Runnable() { 
    public void run() { 
     messageFromSlowStuff = doSomeSlowStuff(); 
     myTextView.setText(messageFromSlowStuff); 
    } 
}); 

Hier ist die Dokumentation View.post in Bezug auf(): "post reference"