我遇到从Android设备到PC的Socket连接问题
在第一次,在LoginActivity中,我的应用程序使用登录名和密码正确连接到带有套接字的服务器
但是,第二次,在CompteActivity中,当我想连接从同一套接字的数据库导入一些数据时,我的应用程序被停止了。
但是,在模拟器中运行没有问题。
在logcat中:
04-21 06:45:26.639: E/AndroidRuntime(13862): FATAL EXCEPTION: main
04-21 06:45:26.639: E/AndroidRuntime(13862): android.os.NetworkOnMainThreadException
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
04-21 06:45:26.639: E/AndroidRuntime(13862): at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
04-21 06:45:26.639: E/AndroidRuntime(13862): at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
04-21 06:45:26.639: E/AndroidRuntime(13862): at libcore.io.IoBridge.connect(IoBridge.java:112)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.Socket.startupSocket(Socket.java:566)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.Socket.tryAllAddresses(Socket.java:127)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.Socket.<init>(Socket.java:177)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.net.Socket.<init>(Socket.java:149)
04-21 06:45:26.639: E/AndroidRuntime(13862): at pfe.mobilebanking.atbmobile.CompteActivity$1.onClick(CompteActivity.java:81)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.view.View.performClick(View.java:3516)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.view.View$PerformClick.run(View.java:14110)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.os.Handler.handleCallback(Handler.java:605)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.os.Handler.dispatchMessage(Handler.java:92)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.os.Looper.loop(Looper.java:137)
04-21 06:45:26.639: E/AndroidRuntime(13862): at android.app.ActivityThread.main(ActivityThread.java:4429)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.lang.reflect.Method.invokeNative(Native Method)
04-21 06:45:26.639: E/AndroidRuntime(13862): at java.lang.reflect.Method.invoke(Method.java:511)
04-21 06:45:26.639: E/AndroidRuntime(13862): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
04-21 06:45:26.639: E/AndroidRuntime(13862): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
04-21 06:45:26.639: E/AndroidRuntime(13862): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:1)
没有代码我无法帮助你,但是这个例外应该指出你正确的方向:
04-21 06:45:26.639: E/AndroidRuntime(13862): android.os.NetworkOnMainThreadException
基本上在较新的操作系统版本(我认为4.0+)中,Google启用了StrictMode,它不允许在主UI线程上访问网络。他们这样做专门用于帮助开发人员,因为网络可以花费不确定的时间,这将阻止用户界面在网络呼叫持续时进行响应或更新。
因此,您需要找到从套接字导入数据的代码,并将其放入AsyncTask,IntentService或其他一些主UI UI线程中。
答案 1 :(得分:0)
确定!在清单中:
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="18" />
<uses-permission
android:name="android.permission.INTERNET"
android:maxSdkVersion="19" />
这是我在LoginActivity和CompteActitvity中的代码......
LoginActivity:
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
String cin = null;
String pass = null;
String reponse = null;
public UserLoginTask(String cin, String pass) {
// TODO Auto-generated constructor stub
this.cin = cin;
this.pass = pass;
}
@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
try {
clientSocket = new Socket(Inet4Address.getByName("192.168.100.1"), 2014);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream());
out.println("connexion");
out.println(cin);
out.println(pass);
out.flush();
reponse = in.readLine();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(reponse.equals("ok"))
return true;
else
return false;
// TODO: register the new account here.
//return true;
}
@Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
String [] numCompte = new String [10];
int i=0;
try {
System.out.println("envoie de INtent");
while(in.ready())
{
numCompte [i] = in.readLine();
System.out.println(numCompte[i]);
i++;
}
clientSocket.close();
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent secondeActivity = new Intent(LoginActivity.this, EspaceClientActivity.class);
secondeActivity.putExtra("numero_compte", numCompte);
startActivity(secondeActivity);
} else {
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
CompteActivity:
OnClickListener afficher = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int select = 0;
float total = 0;
try {
System.out.println("lancement de socket");
Socket clientSocket = new Socket(Inet4Address.getByName("192.168.100.1"), 2014);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream());
out.println("compte");
String [] compteSelected = new String[mNumCompte.length];
for(int i = 0;i<mListCompte.getCount();i++)
{
if(mListCompte.isItemChecked(i))
{
compteSelected [select] = mListCompte.getItemAtPosition(i).toString();
//System.out.println(compteSelected[select]);
out.println(compteSelected[select]);
select++;
}
}
out.flush();
mSoldeCompte = new String[select+1];
for (int i = 0; i<select;i++)
{
reponse = in.readLine();
mSoldeCompte[i]=reponse;
//System.out.println(mSoldeCompte[i]);
total += Float.parseFloat(mSoldeCompte[i]);
}
//System.out.println("Float à ajouter..." + total);
mSoldeCompte[select]= String.valueOf(total).toString();
//System.out.println("valeur ajoutée..."+mSoldeCompte[select]);
String [][] afficheElementSolde = new String[select+1][select+1];
for(int i = 0;i<select;i++)
{
afficheElementSolde[i][0] = compteSelected[i];
}
for(int i = 0;i<select+1;i++)
{
afficheElementSolde[i][1] = mSoldeCompte[i];
}
afficheElementSolde[select][0]="Total";
List<HashMap<String, String>> liste = new ArrayList<HashMap<String, String>>();
HashMap<String, String> element;
for(int i = 0;i<select+1;i++)
{
element = new HashMap<String, String>();
element.put("num_compte", afficheElementSolde[i][0]);
element.put("sol_compte", afficheElementSolde[i][1]);
liste.add(element);
}
//System.out.println("affichage de solde");
ListAdapter adapter = new SimpleAdapter(CompteActivity.this , liste, android.R.layout.simple_list_item_2, new String[] {"num_compte","sol_compte"}, new int[]{android.R.id.text1,android.R.id.text2});
mListSolde.setAdapter(adapter);
clientSocket.close();
in.close();
out.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
只是为了提醒你,这个代码在模拟器中运行没有问题,而在android设备(os版本:4.0.4)中,问题出现在CompteActivity的这一行:
Socket clientSocket = new Socket(Inet4Address.getByName("192.168.100.1"), 2014);
答案 2 :(得分:0)
晚上好 谢谢你的帮助! :) 关于OS 4.0+版本的评论,我把我的代码放到了类中,扩展了AsyncTask 在CompteActivity中,就像你告诉我的那样......
这是我正确运行的新代码:
公共类CompteActivity扩展了Activity {
private UserCompteTask mSoldeTask;
private BufferedReader in = null;
private PrintWriter out = null;
String reponse = null;
Socket clientSocket;
private ListView mListCompte = null;
private ListView mListSolde = null;
private String [] mNumCompte = null;
//private String [] mSoldeCompte = null;
private Button boutonAfficher = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compte);
mListCompte = (ListView)findViewById(R.id.list_num_compte_compte);
mListSolde = (ListView)findViewById(R.id.info_compte);
boutonAfficher = (Button)findViewById(R.id.button_compte_affiche);
boutonAfficher.setOnClickListener(afficher);
Intent chargeNum = getIntent();
mNumCompte = chargeNum.getStringArrayExtra("liste_compte");
mListCompte.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, mNumCompte));
mListCompte.setItemChecked( 0, false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.compte, menu);
return true;
}
OnClickListener afficher = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mSoldeTask = new UserCompteTask();
mSoldeTask.execute((Void) null);
}
};
public class UserCompteTask extends AsyncTask<Void, Void, Boolean>
{
int select = 0;
float total = 0;
private String [] mSoldeCompte = null;
String [] compteSelected = new String[mNumCompte.length];
@Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
// Simulate network access.
Thread.sleep(1000);
} catch (InterruptedException e) {
return false;
}
try
{
clientSocket = new Socket("192.168.100.1", 2014);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream());
out.println("compte");
for(int i = 0;i<mListCompte.getCount();i++)
{
if(mListCompte.isItemChecked(i))
{
compteSelected [select] = mListCompte.getItemAtPosition(i).toString();
//System.out.println(compteSelected[select]);
out.println(compteSelected[select]);
select++;
}
}
out.flush();
mSoldeCompte = new String[select+1];
for (int i = 0; i<select;i++)
{
reponse = in.readLine();
mSoldeCompte[i]=reponse;
//System.out.println(mSoldeCompte[i]);
total += Float.parseFloat(mSoldeCompte[i]);
}
//System.out.println("Float à ajouter..." + total);
mSoldeCompte[select]= String.valueOf(total).toString();
//System.out.println("valeur ajoutée..."+mSoldeCompte[select]);
clientSocket.close();
in.close();
out.close();
}catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
@Override
protected void onPostExecute(final Boolean success) {
mSoldeTask = null;
if (success) {
String [][] afficheElementSolde = new String[select+1][select+1];
for(int i = 0;i<select;i++)
{
afficheElementSolde[i][0] = compteSelected[i];
}
for(int i = 0;i<select+1;i++)
{
afficheElementSolde[i][1] = mSoldeCompte[i];
}
afficheElementSolde[select][0]="Total";
List<HashMap<String, String>> liste = new ArrayList<HashMap<String, String>>();
HashMap<String, String> element;
for(int i = 0;i<select+1;i++)
{
element = new HashMap<String, String>();
element.put("num_compte", afficheElementSolde[i][0]);
element.put("sol_compte", afficheElementSolde[i][1]);
liste.add(element);
}
//System.out.println("affichage de solde");
ListAdapter adapter = new SimpleAdapter(CompteActivity.this , liste, android.R.layout.simple_list_item_2, new String[] {"num_compte","sol_compte"}, new int[]{android.R.id.text1,android.R.id.text2});
mListSolde.setAdapter(adapter);
}
}
@Override
protected void onCancelled() {
mSoldeTask = null;
}
}
}