2016-05-15 81 views
0

我試圖爲應用程序創建窗體。該表單包含兩個edittext字段和一個提交按鈕。無論如何,我得到的「方法getText必須調用從ui線程」錯誤下的doInBackground()。Android Studio方法gettext必須從當前推斷的UI線程調用線程是工作

這是我的代碼:

package com.example.jinson.myapplication; 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.entity.UrlEncodedFormEntity; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.design.widget.FloatingActionButton; 
import android.support.design.widget.Snackbar; 
import android.view.View; 
import android.support.design.widget.NavigationView; 
import android.support.v4.view.GravityCompat; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.app.ActionBarDrawerToggle; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.widget.EditText; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 

public class SubmitUname extends AppCompatActivity { 

private EditText editTextName; 
private EditText editTextUname; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
// TODO Auto-generated method stub 
super.onCreate(savedInstanceState); 
setContentView(R.layout.submit_uname); 

editTextName = (EditText) findViewById(R.id.editName); 
editTextUname = (EditText) findViewById(R.id.editUserName); 


Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
setSupportActionBar(toolbar); 
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
     this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 
drawer.setDrawerListener(toggle); 
toggle.syncState(); 
} 

public void insert(View view){ 
    String name = editTextName.getText().toString(); 
    String uname = editTextUname.getText().toString(); 
    insertToDatabase(name,uname); 
} 

private void insertToDatabase(String name, String uname){ 
    class SendPostReqAsyncTask extends AsyncTask<String, Void, String> { 
    @Override 
    protected String doInBackground(String... params) { 

    String paramUsername = params[0]; 
    String paramAddress = params[1]; 


     String name = editTextName.getText().toString(); 
     String uname = editTextUname.getText().toString(); 

    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
    nameValuePairs.add(new BasicNameValuePair("name", name)); 
    nameValuePairs.add(new BasicNameValuePair("uname", uname)); 

    try { 
     HttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(
       "http://localhost/insert-db.php"); 
     httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

     HttpResponse response = httpClient.execute(httpPost); 

     HttpEntity entity = response.getEntity(); 


    } catch (ClientProtocolException e) { 

    } catch (IOException e) { 

    } 

    return "success"; 
    } 

    @Override 
    protected void onPostExecute(String result) { 
    super.onPostExecute(result); 
    } 
    } 
SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask(); 
    sendPostReqAsyncTask.execute(name, uname); 
    } 

} 

的Android工作室說,法的getText()必須從指令的UI線程調用:editTextName.getText()的toString()。和editTextUname.getText()。toString();可能的解決方案??

我是這個領域的新手,請給我一個解決方案。

+1

在此論壇中有類似的問題。可能是http://stackoverflow.com/questions/32568340/android-studio-error-method-gettext-must-be-called-from-the-ui-thread-curre這將幫助你 – Shriram

+0

你正在創建一個類該方法,你應該在方法外部創建SendPostReqAsyncTask。您無法訪問doInBackground方法中的UI組件。因爲此方法在工作線程中運行。 – USKMobility

+1

你已經傳遞'name'和'uname'並訪問了,那麼爲什麼你需要再次使用'getText()。toString()'? –

回答

0

doInBackground方法不會在UI(主)線程上運行,因此您無法從那裏更新或使用getText()。但好消息是,您可以使用onPostExecute()方法進行處理。

編輯

一個很好的選擇可能是,獲取的AsyncTask之前你EDITTEXT的值,然後將其發送到您的SendPostReqAsyncTask構造。

+2

這不回答問題。 – CommonsWare

+0

@CommonsWare:你的回答與我的不同嗎? –

+0

在編寫我的評論並寫完我的答案後,您編輯了您的答案。我的評論是針對你的原始答案的,沒有解決問題中提到的問題。 – CommonsWare

1

的Android工作室說,getText()方法必須從UI線程

正確調用。如果用戶旋轉屏幕或以其他方式觸發配置更改,則在您撥打doInBackground()的代碼時,您的活動可能會消失。

可能的解決方案?

  • 添加一個構造函數來SendPostReqAsyncTask,並且在任何值傳遞,你需要成,如文本從EditText

  • 制定者添加到SendPostReqAsyncTask並傳入你需要插入任何值其中,如從EditText,文呼籲​​或executeOnExecutor()

鋁前因此請注意:

  • HttpClient的還沒有被推薦爲年,是Android 5.1已被廢棄,並從SDK輾轉到Android 6.0的

  • 使用嵌套類實現的AsyncTask(因爲你正在做的與SendPostReqAsyncTask)將導致內存泄漏時,設備進行配置更改(例如,用戶將設備從縱向旋轉到風景)

相關問題